Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Route parameters, query and body

A handler gets the request object as its first argument — everything the client sent. Most often you take three things from it: route parameters, the query string (query — the part of the address after ?) and the request body (body — data the client sent with POST or PUT).

Route parameters

The part of the address with a colon ends up in request.params. Add a single-post route to src/routes/posts.js:

// src/routes/posts.js
app.get('/posts/:id', async (request) => {
  const id = Number(request.params.id);
  return posts.find((post) => post.id === id);
});

Open http://localhost:3000/posts/2 — the second post appears. Parameters always arrive as strings, so id is converted to a number.

A route can have several parameters:

// src/routes/comments.js
export default async function commentRoutes(app) {
  app.get('/posts/:id/comments/:commentId', async (request) => {
    const { id, commentId } = request.params;
    return { id, commentId };
  });
}

Do not forget to register the new file in src/app.js with app.register(commentRoutes). The address /posts/1/comments/7 returns {"id":"1","commentId":"7"}.

The query string

Fastify collects the parameters after ? into the request.query object:

// src/routes/posts.js
app.get('/posts', async (request) => {
  const limit = Number(request.query.limit ?? 10);
  return posts.slice(0, limit);
});

The address /posts?limit=1 returns only the first post, and /posts without the parameter returns up to ten posts.

The request body

If the client sent JSON with the Content-Type: application/json header, Fastify parses it into request.body:

// src/routes/posts.js
app.post('/posts', async (request) => {
  const { title, body } = request.body;
  const post = { id: posts.length + 1, title, body };
  posts.push(post);
  return post;
});

Send a new post from the terminal:

curl -X POST http://localhost:3000/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"New post","body":"Some text"}'

The server returns the post with id 3, and it shows up in the /posts list — until the server restarts.

What else request has

PropertyWhat it holds
request.paramsRoute parameters
request.queryThe query string
request.bodyThe parsed body
request.headersHeaders, names in lower case
request.ipThe client IP address
request.logThe logger of this request

So far the data is not checked at all: a client can send an empty title or a string instead of a number. Schema validation is added in the chapter on schemas.

Common mistake

Comparing a parameter with a number without converting it never matches:

// src/routes/posts.js
// Wrong: '2' === 2 is false.
posts.find((post) => post.id === request.params.id);

Convert parameters with Number() — or set the type in a schema and Fastify does it for you.

Thanks for reading!

Donate to the site — we work hard for you.