The labs on this site need JavaScript to run. The same content is written out below.
Fundamentals › Networking
How is GET different from POST?
The first word of the first line of an HTTP request is called the method. The method is the word that tells the server what the request wants done at that address, so even for the same /memos address, what the server does depends on whether you send GET or POST. GET is the method that gets something that is on the server; it is not a request to change anything on the server. POST is the method that asks the server to process the content (the body) that is sent with the request. A server writes code for the methods it handles, and if a request comes with a method it has not written code for, it answers with the status code 405. In this lab you send requests to a server that has a list of memos, change the method on the first line, send the same request once or twice, and see what happens to the memos on the server. The upper part of the code box is the text that was actually sent to the server, and a line that starts with # is a note that is not sent to the server (what the server has set up, and how many times the request is sent). The code box is not the code of the server program; it shows what was exchanged. (empty line) is a way to show a line with no text at all, so that you can see it.
Checked against real execution · Ran all 6 combinations by sending the text of the request exactly as it is to an http server on Node.js 24.18.0 and checked against the results
GET /memos HTTP/1.1 Host: localhost:8080 (empty line) # Server: the list at first has one memo, first # Server: GET /memos → returns the list # Server: POST /memos → adds the text of the body to the list
The server was started on an empty port of 127.0.0.1 with the http module of Node.js 24.18.0. At first its list holds one memo, first. For GET /memos it returns 200 OK with the list joined by ", " as the body. For POST /memos it adds the text of the request body to the list and returns 200 OK with the list after the addition as the body. For any other method that comes to /memos, it returns 405 with an Allow: GET, POST line that the server code adds, and for any other address it returns 404. The code box is not the code of the server program; it shows what was exchanged, and a line that starts with # is a note that is not sent to the server. All 6 combinations, 3 methods and 2 numbers of requests, were actually run. The client used the net module and sent the text of the request in the upper part of the code box exactly as it is, with CRLF at the end of each line (when it sent twice, it opened a new connection and sent the same text once more), and it parsed the status line, the Allow line, and the body of the response it received until the server closed the connection. We checked against the model the method, the path, and the body that the server received, the number of memos on the server after the request and whether the list changed, whether the list read by one more GET /memos at the end is the same as the real list of the server, and whether a GET to an address that does not exist, /nothing, gets 404, and we also checked for each combination that the text of the request is the same text that the code on the screen ran. Everything matched the model. Host: localhost:8080 on the screen is an example; the request was actually sent to an empty port, and this server does not look at the value of Host. That GET did not change anything on the server is because we made this server that way. The standard only gives GET the meaning of read-only, so what happens with a server that changes something on a GET was not run. Answering POST with 200 OK is also the choice of this server. The standard recommends answering with 201 Created and a Location line if a new resource was created (section 9.3.3), and we did not use it because a memo of this server has no address of its own. What was checked against the documentation is the following sections of RFC 9110: section 9.1 (method names are case-sensitive, and it recommends 501 for a method that the server does not know or has not implemented, and 405 for a method that it knows but the resource does not accept), section 9.2.1 (safe methods: defined with read-only meaning, so the client neither requests nor expects a change of state on the server), section 9.2.2 (idempotent), section 9.3.1 (GET: a request to transfer the current representation of the target resource), section 9.3.3 (POST: a request that the target resource process the representation enclosed in the request, and its uses), section 10.2.1 (Allow), and section 15.5.6 (405 Method Not Allowed: a method that is known but not supported by the target resource, and the Allow line must be added to a 405 response). We opened these documents with WebFetch, but we opened the long documents in parts and what came back was a summary and short excerpts, so we could not check whole sentences against the original. What this lab does not cover: cases where PUT, PATCH, and DELETE succeed, the property that sending the same request many times gives the same result (idempotency), and whether it is safe to send again when you did not get a response are covered in the in-depth lab "Retries and idempotency"; the shape of the text of requests and responses and all the status codes are covered in the in-depth lab "HTTP messages and status codes"; and how Spring separates requests by method and address is covered in the in-depth lab "Request mapping and parameter binding". We did not use a browser, and we did not check that typing an address in the address bar of a browser sends GET and that an HTML form can use POST.
Previous lab: HTTP requests · Next lab: HTTP responses
Struck-through text was removed from the first version of the code; highlighted text was added.