Building a REST API with Fastify Plugins for Validation and Authentication
Introduction
This guide shows how to create a secure REST API using Fastify with plugin-driven validation via fastify-sensible
and fastify-jwt
. You’ll learn to validate request payloads and protect routes with JSON Web Tokens.
Prerequisites
- Node.js >=16 installed
- NPM or Yarn
- Basic knowledge of JavaScript/TypeScript
Step 1: Initialize the Project
mkdir fastify-auth-api
cd fastify-auth-api
npm init -y
Step 2: Install Dependencies
npm install fastify fastify-sensible fastify-jwt fastify-plugin @sinclair/typebox
Step 3: Configure Fastify Server
Create src/server.ts
:
import Fastify from "fastify";
import sensible from "fastify-sensible";
import jwt from "fastify-jwt";
import authRoutes from "./routes/auth";
async function buildServer() {
const app = Fastify({ logger: true });
app.register(sensible);
app.register(jwt, {
secret: process.env.JWT_SECRET || "supersecret",
});
app.register(authRoutes, { prefix: "/auth" });
return app;
}
if (require.main === module) {
buildServer().then(app => app.listen({ port: 3000 }));
}
export default buildServer;
Step 4: Create Validation Schemas
Create src/schemas/user.ts
:
import { Static, Type } from "@sinclair/typebox";
export const UserSignUp = Type.Object({
username: Type.String({ minLength: 3 }),
password: Type.String({ minLength: 6 }),
});
export type UserSignUpType = Static<typeof UserSignUp>;
Step 5: Implement Authentication Routes
Create src/routes/auth.ts
:
import { FastifyPluginAsync } from "fastify";
import fp from "fastify-plugin";
import { UserSignUp } from "../schemas/user";
const authRoutes: FastifyPluginAsync = async app => {
app.post(
"/signup",
{
schema: { body: UserSignUp },
},
async (request, reply) => {
const { username } = request.body as any;
// TODO: save user to DB
const token = app.jwt.sign({ username });
reply.send({ token });
}
);
app.post("/login", async (request, reply) => {
const { username } = request.body as any;
// TODO: verify credentials
const token = app.jwt.sign({ username });
reply.send({ token });
});
app.get(
"/profile",
{
preValidation: [app.jwt.verify],
},
async request => {
return { user: request.user };
}
);
};
export default fp(authRoutes);
Step 6: Test the API
curl -X POST http://localhost:3000/auth/signup \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"secret123"}'
Summary
You now have a Fastify REST API with schema validation and JWT-based authentication. Extend this by integrating a database, refresh tokens, and role-based access control.