Defining Routes

app.get / app.post / app.route

Defining Routes

Register routes via the convenience methods like app.get and app.post, or use app.route for full control over the route definition.

4 min read Level 1/5 #fastify#routes#handlers
What you'll learn
  • Use app.get, app.post, app.put, app.delete
  • Receive the (request, reply) handler arguments
  • Return values that get serialized to JSON

A Fastify route is a URL plus a handler. There are two styles: per-method shortcuts and the unified app.route form.

Per-Method Shortcuts

app.get('/users', async () => {
  return await db.users.findMany();
});

app.post('/users', async (req) => {
  return await db.users.create(req.body);
});

app.delete('/users/:id', async (req) => {
  await db.users.delete(req.params.id);
  return { deleted: true };
});

Whatever the async handler returns becomes the JSON response body. If you return undefined, Fastify sends an empty payload — return at least {} to be explicit.

The Unified app.route Form

app.route({
  method: 'GET',
  url: '/posts/:id',
  schema: {
    params: {
      type: 'object',
      properties: { id: { type: 'integer' } },
    },
  },
  handler: async (req) => db.posts.find(req.params.id),
});

app.route accepts every option in one object: schema, hooks, config, logLevel, preHandler. It is what the shortcuts call under the hood, and it is the most readable form once a route grows past a few lines.

Handler Arguments

Every handler receives (request, reply). request exposes body, params, query, headers, id, and log. reply is only needed when you want to set a status code, custom header, or stream a response — covered in the reply lesson.

HTTP Methods & app.route →