REST APIs: Concepts, Methods & URL Anatomy (with NestJS examples)
As a former 3D Animator with more than 12 years of experience, I have always been fascinated by the intersection of technology and creativity. That's why I recently shifted my career towards MERN stack development and software engineering, where I have been serving since 2021.
With my background in 3D animation, I bring a unique perspective to software development, combining creativity and technical expertise to build innovative and visually engaging applications. I have a passion for learning and staying up-to-date with the latest technologies and best practices, and I enjoy collaborating with cross-functional teams to solve complex problems and create seamless user experiences.
In my current role as a MERN stack developer, I have been responsible for developing and implementing web applications using MongoDB, Express, React, and Node.js. I have also gained experience in Agile development methodologies, version control with Git, and cloud-based deployment using platforms like Heroku and AWS.
I am committed to delivering high-quality work that meets the needs of both clients and end-users, and I am always seeking new challenges and opportunities to grow both personally and professionally.
What is a REST API (in plain words)?
A REST API is an HTTP-based interface that follows the Representational State Transfer principles. If your API follows these principles, we call it “RESTful.”
At a high level: a client (browser, mobile app, another server) sends an HTTP request to a server, and the server returns an HTTP response. NestJS helps you build the server side cleanly.
The 6 REST principles (we’ll use 5 of them a lot)
Client–Server: UI (client) and data/services (server) are separate. Clients consume endpoints; server doesn’t care who the client is.
Stateless: Every request carries all info the server needs (e.g., an
Authorization: Bearer <token>header). The server doesn’t keep a per-user session.Cacheable: Responses may be cached by clients or servers (independently) to improve speed and scalability.
Uniform Interface: Consistent resource‑oriented URLs and standard methods (GET/POST/PUT/PATCH/DELETE). Same request → same shape of response, regardless of who sends it.
Layered System: Requests often pass through layers (load balancer, cache, app servers, DB). Neither client nor server needs to know the intermediaries.
Code on Demand (optional): Server can send executable code to clients. Rarely used in typical JSON APIs and not needed for this course.

HTTP methods you’ll use (cheat sheet)


| Method | Typical Use | Blog example | Idempotent? |
| GET | Read/fetch data | GET /posts, GET /posts/:id | ✅ Yes |
| POST | Create a resource | POST /posts | ❌ No |
| PUT | Replace an entire resource | PUT /posts/:id (send full post) | ✅ Yes |
| PATCH | Update part of a resource | PATCH /posts/:id (send only changed fields) | ❌ Usually not |
| DELETE | Remove a resource | DELETE /posts/:id | ✅ Yes |
Quick tip: If you’re updating everything, use PUT. If you’re updating just a few fields, use PATCH.




The anatomy of an API request


Example:
GET https://api.example.com/posts/author/42?limit=10&offset=20
Method:
GETDomain:
https://api.example.comRoute (path):
/posts/author/42Params:
author = 42(often expressed as:authorin route templates)Query string:
?limit=10&offset=20(extra filters/pagination)Headers (not shown): e.g.,
Authorization: Bearer <token>Body: Only for methods like POST/PUT/PATCH (usually JSON)
Example request bodies (JSON)
Create a post
{
"title": "Why NestJS Rocks",
"description": "A quick tour of modules and decorators",
"modifiedAt": "2025-09-03T09:00:00.000Z",
"authorId": 42
}
Partial update (PATCH)
{
"title": "Why NestJS Still Rocks"
}

How this maps to NestJS (controllers)
// posts.controller.ts
import { Controller, Get, Param, Query, Post, Body, Put, Patch, Delete } from '@nestjs/common';
@Controller('posts')
export class PostsController {
@Get()
findAll(@Query('limit') limit?: number, @Query('offset') offset?: number) {
return { message: 'List posts', limit, offset };
}
@Get('author/:authorId')
findByAuthor(@Param('authorId') authorId: string) {
return { message: 'Posts by author', authorId };
}
@Post()
create(@Body() dto: any) {
return { message: 'Create post', dto };
}
@Put(':id')
replace(@Param('id') id: string, @Body() dto: any) {
return { message: 'Replace post', id, dto };
}
@Patch(':id')
update(@Param('id') id: string, @Body() dto: any) {
return { message: 'Update post', id, dto };
}
@Delete(':id')
remove(@Param('id') id: string) {
return { message: 'Delete post', id };
}
}
Key decorators
@Controller('posts')→ base route/posts@Get(),@Post(),@Put(),@Patch(),@Delete()→ methods@Param('id')→ route params like:id@Query('limit')→ query string values@Body()→ JSON payload for create/update
We’ll later add DTOs and validation pipes to make inputs type‑safe and clean.

Testing your API during development
You don’t need a frontend to test. Use any of these:
Postman — GUI client for sending requests
httpyac (VS Code extension) — lets you save
.httpfiles inside your repocurl — simple command‑line tool
Example .http (httpyac/REST Client)
### List posts (first page)
GET http://localhost:3000/posts?limit=10&offset=0
### Posts by author
GET http://localhost:3000/posts/author/42
### Create post
POST http://localhost:3000/posts
Content-Type: application/json
Authorization: Bearer {{token}}
{
"title": "My first NestJS post",
"description": "Hello, world!",
"authorId": 42
}
Params vs Query (mental model)
Params (part of the path) = category or identity
/posts/:id→ one specific post/posts/author/:authorId→ posts by an author
Query (after
?) = filters/sorting/pagination?limit=10&offset=20?sort=createdAt&order=desc
Common pitfalls
Mixing up PUT and PATCH (replace vs partial update)
Hiding state on the server (REST should be stateless — pass tokens on each request)
Inconsistent routes (stick to nouns and plural resources, e.g.,
/posts,/users)Returning different shapes for the same endpoint (breaks uniform interface)
Practice (do this now)
Create a
PostsControllerwith the handlers shown above and return simple JSON.Hit the endpoints with Postman or an
.httpfile. Play with:authorId,limit,offset.Add a
POST /poststhat accepts the JSON body and echoes it back.Try
PUTvsPATCHon the same:idand note the semantic difference.