Inspect a request
- Lesson 3
- 35 min
- Module 1: Understand the web request
Lesson 3 of 21 · Build and Deploy Your First APIInspect a request
1. Understand the web request
2. Build a small FastAPI service
3. Design a usable contract
4. Document the API with OpenAPI and Swagger UI
5. Explore and test with Postman
6. Test and harden the service
7. Deploy and verify
What you will be able to do
See exactly what a client sent and what the server answered, with two tools that you always have: the browser’s developer tools and curl. When an API “does not work”, this is the first thing to check.
Before you startWhat to know and to have ready
What you need to know
- The parts of a request and a response, from HTTP fundamentals: A request, part by part and HTTP fundamentals: Status codes.
- The steps of a request, from Browser-to-server basics: The whole journey. curl shows them in this lesson.
What you need on your computer
- A desktop browser: Chrome, Edge or Firefox. Safari works too, after you turn on Settings › Advanced › Show features for web developers.
- curl. It is included in macOS, Windows 10 and 11, and most Linux systems. On Windows, type
curl.exe(see below). - An internet connection. The examples use Postman Echo and the course’s public data file.
Tested with curl 8.7 on macOS and Chrome 141.
The browser’s developer tools
Section titled “The browser’s developer tools”Every desktop browser has developer tools: a panel that shows what a page does. The Network tab lists every request that the page makes, with its full request and response.
- Open a new browser tab.
- Open the developer tools: press F12, or Cmd+Option+I on macOS. Select the Network tab.
- In the address bar, open
https://raw.githubusercontent.com/Nextia-Intelligence/nextia-learning-labs/main/C02/data/tickets.json. - In the Network tab, select the row
tickets.json. - Look at Headers. Find the request method (
GET), the status code (200), and the response headercontent-type. - Look at Response (or Preview). It shows the body: the 15 tickets.
The developer tools show requests that the browser makes. They are the best tool when a web page uses your API, because you see the request exactly as that page sends it. To send a request that you design, use curl.
curl sends one request from the terminal, and shows the response. Each part of the request is an option:
| Option | Meaning |
|---|---|
-i |
Show the response headers, not only the body. |
-v |
Show everything: DNS, connection, TLS, the request headers and the response headers. |
-X POST |
Use this method. Without it, curl uses GET. |
-H "Name: value" |
Add a request header. |
--data @file.json |
Send the contents of this file as the body. |
-s |
Silent: no progress bar. |
Worked example: a request and its response
Section titled “Worked example: a request and its response”Amira sends a GET and shows the response headers with -i:
curl -i "https://postman-echo.com/get?status=open"HTTP/2 200content-type: application/json; charset=utf-8content-length: 231server: cloudflare
{"args":{"status":"open"},"headers":{"host":"postman-echo.com","accept":"*/*","user-agent":"curl/8.7.1",...},"url":"https://postman-echo.com/get?status=open"}Read it from the top: the protocol and status code (HTTP/2 200), the response headers, an empty line, then the body. Postman Echo’s body shows what it received: the query parameter, and the headers that curl added for her (accept, user-agent).
Then she sends a POST with a JSON body. First, she saves the body in a file, ticket.json:
{"subject": "Charged twice for March", "body": "Same invoice two times."}curl -i -X POST https://postman-echo.com/post -H "Content-Type: application/json" --data @ticket.jsonHTTP/2 200content-type: application/json; charset=utf-8
{"data":{"subject":"Charged twice for March","body":"Same invoice two times."},"headers":{"content-type":"application/json",...},"json":{"subject":"Charged twice for March","body":"Same invoice two times."},...}The json field shows that the server read the body as JSON, because of the Content-Type header.
See every step with -v
Section titled “See every step with -v”-v (verbose) shows the steps from Browser-to-server basics. Lines that start with * are curl’s notes, > is what curl sent, and < is what it received. Here, Postman Echo returns a 503 on purpose:
curl -v https://postman-echo.com/status/503* Host postman-echo.com:443 was resolved.* Connected to postman-echo.com (162.159.142.41) port 443* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256> GET /status/503 HTTP/2> Host: postman-echo.com< HTTP/2 503< content-type: application/json; charset=utf-8{"status":503}DNS worked (was resolved), the connection worked (Connected ... port 443), TLS worked (SSL connection using TLSv1.3), and the request was sent. The server answered with 503. The network worked completely. The application reported a problem. This is the most important difference in this module.
Guided practice: inspect two requests
Section titled “Guided practice: inspect two requests”-
Make a folder for this module’s practice files, and move into it:
Terminal window mkdir -p ~/projects/http-practicecd ~/projects/http-practiceOn Windows,
mkdir ~/projects/http-practiceworks without-p. -
Make
ticket.jsonwith the body from the worked example. -
Send it with
curl -i -X POST, as in the worked example. Find the status code, thecontent-typeheader, and thejsonfield in the body. -
Send the same request without the
-H "Content-Type: application/json"option. Compare the response. Which header did curl send instead? (Look in theheadersfield of the body.) -
Run
curl -v https://postman-echo.com/status/404. Find the line that shows the connection, the line that shows the request, and the line with the status code.
Show what you should see in step 4
Without your header, curl sends content-type: application/x-www-form-urlencoded, the format of an HTML form. So Postman Echo reads the body as a form. In the form field, the whole JSON text is the name of one field, with an empty value. The server did what the header said. The API that you build answers 422 for the same request. Always send the Content-Type header with a body.
Your turn: read a response you did not design
Section titled “Your turn: read a response you did not design”Open the developer tools on any web page that you use often, and reload the page. Find one request whose response type is JSON (the Type column shows fetch, xhr or json). For that request, write down:
- The method, the host and the path.
- Two request headers, and what you think each one is for.
- The status code, and the response
content-type. - One field from the response body, and what you think it means.
There is no single right answer. The goal is to read a real request part by part, as you will read your own API’s requests.
Common mistake
A successful connection with an application error
Symptom: a request “fails”, and you start to check the internet connection, the firewall or DNS. But curl shows a status code, such as 404, 422 or 500.
Cause: any status code proves that DNS, the connection and TLS worked, and that the application answered. The problem is in the request (a 4xx code) or in the application (a 5xx code), not in the network.
Fix:
- Run the request with
curl -v. If you see a< HTTP/...line with a status code, the network is fine. - For a
4xxcode, read the response body. A good API says what is wrong with the request. - For a
5xxcode, read the application’s logs. The client cannot fix it. - Only if there is no status code (
Could not resolve host,Couldn't connect to server, a timeout or an SSL error), check the URL, the network and the server.
Check your understanding
Module check: curl -v shows 'Connected to api.example.com port 443', a TLS line, and then '< HTTP/2 500'. Explain why the network connection worked but the request still failed, and who must fix it.
Show the answer
The connection line and the TLS line show that DNS, the connection and the encryption all worked, and the server received the request. 500 is the application’s answer: it had an unexpected error while it handled the request. The network is fine, and sending the same request again usually does not help. The people who run the API must fix it, with the help of its logs. If it were 503, a later attempt could work. If it were a 4xx code, the client would have to change the request.
Does your answer have the main points of ours?
Sign in and enroll in the course to save your answers. Every check counts toward the certificate.
Check your understanding
Why does this course send JSON bodies from a file with --data @ticket.json, instead of typing the JSON in the command?
Show the answer
Typing JSON in a command depends on the shell’s rules for quotes, and Windows PowerShell changes the quotes before curl receives them. A file avoids the shell completely, so the same command works on macOS, Linux and Windows. The file is also easy to read, change and keep with the project.
Does your answer have the main points of ours?
Sign in and enroll in the course to save your answers. Every check counts toward the certificate.
Recap
- The Network tab in the developer tools shows every request that a page makes, with its headers and body.
- curl sends a request that you design:
-ishows the response headers,-vshows every step,-X,-Hand--data @file.jsonbuild the request. On Windows, typecurl.exe. - A status code means that the network worked and the application answered. Without a status code, the failure is in the URL, the network or the server.
You can now read any request and response. In the next module, you build the server side: a FastAPI service.