Fullstack CourseLearn by building
Back to week 1

Topic

REST API + Postman / curl

Definition

Exercising a REST API with a tool such as curl or Postman means issuing HTTP requests with an explicit method, URL, headers, and body, and inspecting the returned status code and JSON — independent of any frontend UI.

In simpler words

Before relying on React, you should be able to call Nest routes yourself with curl or Postman and predict exactly what comes back.

Hands-on API practice for the week: hit /health, walk authenticated CRUD routes, and read ValidationPipe / filter errors.

After this you can

  • Call GET /health with curl and read the JSON
  • Call authenticated list/create routes with the correct headers and body
  • Carry a login cookie across curl requests (or via Postman’s cookie jar)
  • Read errors returned by ValidationPipe and AllExceptionsFilter
  • Find and use the Swagger UI at /docs instead of guessing routes

Start with the public route: /health

Definition

A public route is a Nest handler marked to bypass the global authentication guard, making it reachable without any credentials — a natural first target for verifying an API is running.

In simpler words

/health needs no login, so it is the fastest way to confirm the API is up before testing anything that requires a cookie.

HealthController marks its single route @Public(), so JwtAuthGuard (global via APP_GUARD) skips authentication for it entirely.

A quick curl to /health with no headers should return { "status": "ok" } with a 200 — if that fails, nothing else in the API will work either, so always check it first.

Calling health

curl -i http://localhost:3000/health
# HTTP/1.1 200 OK
# { "status": "ok" }

No -H Cookie needed — @Public() skipped the auth guard.

Tickets CRUD with curl — including the cookie

Definition

Because JwtAuthGuard is registered globally, every tickets route requires a valid access_token cookie obtained by first authenticating, which curl must forward explicitly using its cookie-jar flags.

In simpler words

Log in first to get a cookie, save it to a file, then pass that file back on every tickets request — otherwise you will get a 401 before your request even reaches the controller.

curl does not keep cookies between separate invocations by default — use -c cookies.txt to save the Set-Cookie response from login, then -b cookies.txt on every later request to send it back.

The list/get/create/update routes are open to any authenticated user; only DELETE :id requires the admin role via @Roles("admin") — expect a 403 if you try it as a non-admin seed user.

Login, then call tickets (curl)

# 1. Log in and save the cookie
curl -i -c cookies.txt -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@course.local","password":"password123"}'

# 2. List tickets using the saved cookie
curl -b cookies.txt "http://localhost:3000/tickets?page=1&limit=20"

# 3. Create a ticket
curl -b cookies.txt -X POST http://localhost:3000/tickets \
  -H "Content-Type: application/json" \
  -d '{"title":"Wire cookies"}'

# 4. Delete as admin (member gets 403)
curl -b cookies.txt -X DELETE http://localhost:3000/tickets/<id>

The same cookie file authenticates every subsequent request, exactly like a browser would.

Mistake: forgetting the cookie jar

// Wrong — no cookie flags, guard rejects every call
curl -X POST http://localhost:3000/tickets -d '{"title":"x"}'
# 401 Unauthorized

// Right
curl -b cookies.txt -X POST http://localhost:3000/tickets \
  -H "Content-Type: application/json" -d '{"title":"x"}'

Without -b cookies.txt, curl sends no cookie at all — the global JwtAuthGuard rejects the request before TicketsController runs.

Postman, Swagger, and reading errors

Definition

Postman offers a persistent cookie jar and saved collections as an alternative to curl, while Nest’s Swagger UI (served from SwaggerModule.setup) documents and lets you try every route from the running application’s own metadata.

In simpler words

Postman remembers cookies for you across requests in a collection; Swagger at /docs shows every real route with an "Authorize" button so you rarely have to guess a path or body shape.

In Postman, cookies persist automatically for requests inside the same collection/workspace, unlike separate curl invocations that each need explicit -b/-c flags.

apps/api serves Swagger at /docs (SwaggerModule.setup("docs", app, ...)) with addCookieAuth("access_token") configured — after logging in via a route, Authorize with the cookie so "Try it out" sends it automatically.

A validation failure returns 400 with a message array (from class-validator) listing each broken field; any other unhandled error returns the same shape from AllExceptionsFilter with a correlationId you can grep in server logs.

A validation error body

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["title must be longer than or equal to 1 characters"],
  "details": [{ "field": "request", "message": "..." }],
  "correlationId": "..."
}

Same shape for every endpoint — that is the point of one global ValidationPipe + one global filter.

Keep in mind

  • Always test /health first — it rules out "the API isn’t even running".
  • Save curl cookie jars per role (admin vs member) to quickly demonstrate 403 vs success.
  • Swagger is generated from real decorators — if a route is missing there, check @ApiTags/@ApiCookieAuth and that its module is imported by AppModule.
  • Read the message array in error responses before guessing which DTO field is wrong.

Test

Check your understanding

At least 10 questions — mix of concept, syntax, practical, and logic. Score ≥ 80% (enforced by the API) to save progress.

Checking your session…

10 questions · concept 3 · syntax 2 · practical 3 · logic 2

Concept1. Which statement best defines testing the REST API with curl or Postman?
Syntax2. Which code-level choice matches testing the REST API with curl or Postman?
Practical3. A reviewer spots a bug related to testing the REST API with curl or Postman. What is the right fix?
Logic4. Which reasoning correctly explains testing the REST API with curl or Postman?
Concept5. Which boundary does correct use of testing the REST API with curl or Postman preserve?
Practical6. What is the safest next step when applying testing the REST API with curl or Postman?
Syntax7. Which implementation direction matches the rule for testing the REST API with curl or Postman?
Logic8. Which consequence follows from applying testing the REST API with curl or Postman correctly?
Concept9. Which claim about testing the REST API with curl or Postman is true in this Nest + Postgres monorepo?
Practical10. Which team practice best demonstrates testing the REST API with curl or Postman?