fast-maker
generate fastify.js route configuration using by directory structure.
Why fast-maker
?
- Zeor cost for routing configuration at runtime
- Static analysis: The
fast-maker
generates the TypeScript source code. Because it does not generate theroute configuration
through dynamic analysis at runtime, it can find errors during the TypeScript compilation process - flexible routing: supports various routing such as variable joining, regular expressions, etc. for example,
/student/:grade-:id
and/hero/:id/power/:id?
,/avengers/heroes/:id/:hour(^d{2})h:minute(^d{2})m
- single way: there is only one way to generate one routing configuration, so there is no risk of generating routing configurations in different ways even when collaborating
- less code conflicts: by excluding auto-generated code from the VCS(eg. git), there is less chance of code conflicts when people collaborate
- beautiful CLI interface
- generate a route-map.ts file that summarizes routing information. It can be used for a variety of purposes, including logging. The route-map.ts file is useful because it is generated before run-time
- Getting started
- How it works?
- Installation
- Usage
- Url building
- Example using fastify.js
- Relate To
- Roadmaps
- License
npx fast-maker init
npx fast-maker route
You can create configuration file using init command. And you can run route command, fast-maker
generate route.ts
file on your output directory in configuration file.
You can see this mechanics!
fast-maker
using TypeScript Compiler API. So fast-maker
exactly know handler function and route option in each file.
graph LR
A[route file] --> fast-maker
subgraph fast-maker
direction TB
C[TypeScript Compiler API]-->|extract <br/>handler function,<br /> option variable|B[fast-maker]
end
fast-maker-->|extract <br />route path|D[route.ts]
The image below briefly shows how the directory is converted to route configurations.
AS-IS (directory structure) | TO-BE (route function) | |
---|---|---|
➜ |
npm i fast-maker --save-dev
You can see help from --help
option.
# display help for each commands
npx fast-maker --help
# display help for route commands
npx fast-maker route --help
# display help for init commands
npx fast-maker init --help
Also you can see detail option here.
The figure above shows at a quick look how fast-maker
generates a route configuration. Routing with a file-system is intuitive and easy to understand, and it also allows many people to collaborate . This concept borrows from Next.js routing system. However, I've improved it to determine the http method as the filename.
file-system
/handlers/example/[userId]/get.ts
generated TypeScript code like that,
// parametric
fastify.route({
method: ['get'],
url: '/example/:userId',
handler: function (request, reply) {
// curl ${app-url}/example/12345
// userId === '12345'
const { userId } = request.params;
// your code here
}
});
file-system
/handlers/[lat]-[lng]/radius/[[r]]/patch.ts
generated TypeScript code like that,
fastify.route({
method: ['patch'],
url: '/example/near/:lat-:lng/radius/:r?',
handler: function (request, reply) {
// curl ${app-url}/example/near/15°N-30°E/radius/20
// lat === "15°N"
// lng === "30°E"
// r ==="20"
const { lat, lng, r } = request.params;
// your code here
}
});
file-system
/handlers/example/at/[$time]/get.ts
replace map in get.ts
// replace map
const map = new Map<string, string>(['$time', ':hour(^\\d{2})h:minute(^\\d{2})m'])
generated TypeScript code like that,
fastify.route({
method: ['get'],
url: '/example/at/:hour(^\\d{2})h:minute(^\\d{2})m',
handler: function (request, reply) {
// curl ${app-url}/example/at/08h24m
// hour === "08"
// minute === "24"
const { hour, minute } = request.params;
// your code here
}
});
You can pass RouteShorthandOptions
option like that,
// When not using a `fastify` instance, you can declare it as a variable like this
export const option: RouteShorthandOptions = {
schema: {
querystring: schema.properties?.Querystring,
body: schema.properties?.Body,
},
};
When using the fastify
instance, you can declare it as a function like this,
// completly same,
// export function option(fastify: FastifyInstance): RouteShorthandOptions { ... }
export const option = (fastify: FastifyInstance): RouteShorthandOptions => {
return {
schema: {
querystring: schema.properties?.Querystring,
body: schema.properties?.Body,
},
preHandler: fastify.auth([
fastify.allowAnonymous,
fastify.verifyBearerAuth
]),
};
};
You have to named export
and variable name must be a option
.
You can pass route handler function like that,
import { FastifyRequest } from 'fastify';
import type { IReqSearchPokemonQuerystring, IReqSearchPokemonParams } from '../../interface/IReqSearchPokemon';
export async function handler(
req: FastifyRequest<{ Querystring: IReqSearchPokemonQuerystring; Params: IReqSearchPokemonParams }>,
) {
console.debug(req.query);
console.debug(req.body);
return 'hello';
}
You have to named export
and variable name must be a handler
. Also you can use arrow function, as well as type arguments perfectly applied on route configuration.
A complete example of using fast-maker
can be found at Ma-eum and examples
- ts-morph
- TypeScript Compiler API wrapper
- display each route path in cli-table
- add new option silent
- documentation site
- add more test
This software is licensed under the MIT.