Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Fundamentals › Networking

HTTP methods

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

Concepts in this lab

HTTP methods
The part of an HTTP request that indicates the action the request wants to perform on a resource. GET means read, POST means create or a processing request, PUT means replace the whole resource, PATCH means modify part of it, and DELETE means delete. Use each one according to its meaning so that HTTP behavior such as caching and retries works as expected.
GET method
GET is the HTTP method that requests the current content of the target resource (RFC 9110 section 9.3.1). GET is a "safe" method that is defined with a read-only meaning, so a client that sends GET neither requests nor expects a change of state on the server (section 9.2.1). So sending the same GET many times does not usually change what is left on the server. Even if you send a body with a GET request, that body generally has no defined meaning (section 9.3.1).
POST method
POST is the HTTP method that asks the target resource to process the body (the content) sent with the request according to its own rules (RFC 9110 section 9.3.3). Typical uses are handing the values written in an HTML form to a processing program, posting a message to a place like a bulletin board, creating a new resource that has not been identified yet, and appending data to the content of an existing resource. POST is neither a safe method nor an idempotent method (section 9.2), so if you send the same POST twice, the server may process it twice. If a new resource was created as a result, the server is recommended to answer with the 201 Created status code and a Location header (section 9.3.3).
405 Method Not Allowed and the Allow header
405 Method Not Allowed is a status code that means the server knows the method on the request line, but the target of the request does not support that method (RFC 9110 section 15.5.6). The server must add an Allow header to a 405 response to tell the methods that the target currently supports (sections 15.5.6 and 10.2.1). For example, Allow: GET, POST means that the target accepts GET and POST. When the server does not know the method at all or has not implemented it, it is recommended to answer with 501 Not Implemented, not 405 (section 9.1).

Try these

Running with the default settings

  1. The client (the side that sends the request) sends the text below to the server. This text is the HTTP request. The server starts with a list that holds one memo, first. The first word of the first line is the method, and it shows what the request wants the server to do. The method of this request is GET. /memos after it is the path, which address the request is for, and HTTP/1.1 is the version, which rules the text was written by.
  2. The server starts to read the text. From the first line it reads that the method is GET and the path is /memos. The server looks through what it has set up (the # Server lines under the code box) for the same method and path. It has a line that handles the GET /memos request.
  3. The server does the job written on the GET /memos line. It only reads the list and puts it in the response, and does not touch the list, so the server still has 1 memo. The text it puts in the response is "first".
  4. The client gets the response. The status is 200 OK and the body is "first".

Result of this run

Code

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

Assumptions of this model

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

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these