File based routing for fastify (v4). If you want to use this library with fastify v3, you should use version 2.X If you want to use this library with fastify v2, you should use version 1.X
For the given folder structure
├── src
├── routes -- routes folder (can be changed)
| ├── user -- user resource endpoint folder
| | └──index.ts -- has POST method function
| | └──[id].ts -- has GET & PUT method functions
| └── index.ts
└── index.ts -- server file
will result:
└── / (GET)
└── user (POST)
└── /
└── :id (GET)
:id (PUT)
Path params can also be prefixed with :
E.g. :id
instead of [id]
The plugin will ignore any .{test|spec|bench}.js
files when loading routes
The latest version is 2.X which supports fastify v3. If you want to use this library with fastify v2, you should use version 1.X
npm install fastify-now
In your main server file (can see in example folder)
import fastify from 'fastify';
import path from 'path';
import fastifyNow from 'fastify-now';
const server = fastify({ logger: true });
server.register(fastifyNow, {
routesFolder: path.join(__dirname, './routes'),
/**
* Can also provide a prefix
*/
// pathPrefix: '/api'
});
const PORT = Number(process.env.PORT) || 5000;
server.listen({ port: PORT }).then(() => {
// ...
});
In each route file, you need to export a function with a supported HTTP method as the function name, in uppercase letters
Currently supported HTTP methods: GET, POST, DELETE & PUT
In /routes/user/:id/index.ts
:
import { NowRequestHandler } from 'fastify-now';
export const GET: NowRequestHandler<{ Params: { id: string } }> = async (req, rep) => {
return { userId: req.params.id };
};
export const PUT: NowRequestHandler<{ Params: { id: string } }> = async (req, res) => {
req.log.info(`updating user with id ${req.params.id}`);
return { message: 'user updated' };
};
// with the server instance as the context (aka this)
export const POST: NowRequestHandler<{ Body: { name: string } }> = async function(req, res) {
// this = fastify instance
const [user] = await this.db.query(`SELECT * FROM users WHERE name = ${req.body.name}`);
// ... rest of code
}
Dynamic params are specified in the file name, or the folder name.
routes/user/:id/index.ts
- will resolve to /user/:id
routes/book/:id/chapter/:chapterId.ts
- will resolve to /book/:id/chapter/:chapterId
You can also add endpoint fastify opts.
For that, I created a new interface called NowRequestHandler
.
in /routes/user/index.ts
:
import { NowRequestHandler } from 'fastify-now';
type Post = NowRequestHandler<{
Body: { name: string };
Params: { id: string };
Reply: { message: string } | { userId: string };
}>;
export const POST: Post = async (req, rep) => {
if (req.body.name === 'Jon Doe') {
/**
* in async function, you can return undefined if you already sent a response
* then it won't try to send a response again with the returned value;
*/
rep.status(400).send({ message: 'Name can not be Jon Doe' });
return;
}
return { userId: req.params.id };
};
POST.opts = {
schema: {
body: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
required: ['name'],
},
},
};
Licensed under MIT