|
| 1 | +# fast-maker |
| 2 | + |
| 3 | + |
| 4 | +[](https://npmcharts.com/compare/fast-maker?minimal=true) |
| 5 | +[](https://github.com/imjuni/fast-maker) |
| 6 | +[](https://github.com/imjuni/fast-maker/issues) |
| 7 | +[](https://www.npmjs.com/package/fast-maker) |
| 8 | +[](https://github.com/imjuni/fast-maker/blob/master/LICENSE) |
| 9 | +[](https://github.com/imjuni/fast-maker/actions/workflows/ci.yml) |
| 10 | +[](https://codecov.io/gh/imjuni/fast-maker) |
| 11 | +[](https://github.com/prettier/prettier) |
| 12 | + |
| 13 | +`fast-maker` generate fastify.js route configuration using by directory structure. |
| 14 | + |
| 15 | +Why `fast-maker`? |
| 16 | + |
| 17 | +fastify.js already have auto route mechanics using [fastify-autoload](https://github.com/fastify/fastify-autoload). But why you have to use `fast-maker`? |
| 18 | + |
| 19 | +1. [Static analysis](https://en.wikipedia.org/wiki/Static_program_analysis): `fast-maker` generate TypeScript source code. Because it help to find error in compile-time, not runtime |
| 20 | +2. Complex Variable: You can use like that: `/person/[kind]-[id]/`. It help to get id and kind of id, for example serial-number and id or db-pk and id |
| 21 | +3. Next.js: `fast-maker` use the same mechanics as [Next.js](https://nextjs.org/docs/routing/introduction) |
| 22 | +4. `fast-maker` support a beautiful cli-interface |
| 23 | + |
| 24 | +## Table of Contents <!-- omit in toc --> |
| 25 | + |
| 26 | +- [Getting started](#getting-started) |
| 27 | +- [How it works?](#how-it-works) |
| 28 | +- [Installation](#installation) |
| 29 | +- [Usage](#usage) |
| 30 | +- [Routing](#routing) |
| 31 | + - [HTTP Method](#http-method) |
| 32 | + - [Route options](#route-options) |
| 33 | + - [Route handler](#route-handler) |
| 34 | + - [Variable in Route Path](#variable-in-route-path) |
| 35 | +- [Example using fastify.js](#example-using-fastifyjs) |
| 36 | +- [Relate To](#relate-to) |
| 37 | +- [Roadmaps](#roadmaps) |
| 38 | +- [License](#license) |
| 39 | + |
| 40 | +## Getting started |
| 41 | + |
| 42 | +```bash |
| 43 | +npx fast-maker init |
| 44 | +npx fast-maker route |
| 45 | +``` |
| 46 | + |
| 47 | +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. |
| 48 | + |
| 49 | +You can see this mechanics! |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | +## How it works? |
| 54 | + |
| 55 | +`fast-maker` using **TypeScript Compiler API**. So `fast-maker` exactly know handler function and route option in each file. |
| 56 | + |
| 57 | +```mermaid |
| 58 | +graph LR |
| 59 | +
|
| 60 | +A[route file] --> fast-maker |
| 61 | +subgraph fast-maker |
| 62 | +direction TB |
| 63 | +C[TypeScript Compiler API]-->|extract <br/>handler function,<br /> option variable|B[fast-maker] |
| 64 | +end |
| 65 | +fast-maker-->|extract <br />route path|D[route.ts] |
| 66 | +``` |
| 67 | + |
| 68 | +The image below briefly shows how the directory is converted to route configurations. |
| 69 | + |
| 70 | +| AS-IS (directory structure) | | TO-BE (route function) | |
| 71 | +| ---------------------------------------------------------- | --- | -------------------------------------------------- | |
| 72 | +|  | ➜ |  | |
| 73 | + |
| 74 | +## Installation |
| 75 | + |
| 76 | +```basn |
| 77 | +npm i fast-maker --save-dev |
| 78 | +``` |
| 79 | + |
| 80 | +## Usage |
| 81 | + |
| 82 | +You can see help from `--help` option. |
| 83 | + |
| 84 | +```bash |
| 85 | +# display help for each commands |
| 86 | +npx fast-maker --help |
| 87 | + |
| 88 | +# display help for route commands |
| 89 | +npx fast-maker route --help |
| 90 | + |
| 91 | +# display help for watch commands |
| 92 | +npx fast-maker watch --help |
| 93 | + |
| 94 | +# display help for init commands |
| 95 | +npx fast-maker init --help |
| 96 | +``` |
| 97 | + |
| 98 | +Also you can see detail option [here](/docs/options.md). |
| 99 | + |
| 100 | +## Routing |
| 101 | + |
| 102 | +`fast-maker` has a file-system based route configuration. This concept borrowed from [Next.js routing system](https://nextjs.org/docs/routing/introduction). But one difference is that _HTTP Method_ is separated by file-system. |
| 103 | + |
| 104 | +### HTTP Method |
| 105 | + |
| 106 | +use file-system. |
| 107 | + |
| 108 | +```text |
| 109 | +handlers/ |
| 110 | +├─ get/ |
| 111 | +│ ├─ hero/ |
| 112 | +│ │ ├─ [name].ts |
| 113 | +├─ post/ |
| 114 | +│ ├─ hero.ts |
| 115 | +├─ put/ |
| 116 | +│ ├─ hero/ |
| 117 | +│ │ ├─ [name].ts |
| 118 | +├─ delete/ |
| 119 | +│ ├─ hero/ |
| 120 | +│ │ ├─ [name].ts |
| 121 | +``` |
| 122 | + |
| 123 | +`get`, `post`, `put`, `delete` directory represent _HTTP Method_. Also you can use `options`, `patch`, `head`, `all` directory. |
| 124 | + |
| 125 | +### Route options |
| 126 | + |
| 127 | +You can pass `RouteShorthandOptions` option like that, |
| 128 | + |
| 129 | +```ts |
| 130 | +export const option: RouteShorthandOptions = { |
| 131 | + schema: { |
| 132 | + querystring: schema.properties?.Querystring, |
| 133 | + body: schema.properties?.Body, |
| 134 | + }, |
| 135 | +}; |
| 136 | +``` |
| 137 | + |
| 138 | +You have to `named export` and variable name must be a `option`. |
| 139 | + |
| 140 | +### Route handler |
| 141 | + |
| 142 | +You can pass route handler function like that, |
| 143 | + |
| 144 | +```ts |
| 145 | +import { FastifyRequest } from 'fastify'; |
| 146 | +import type { IReqSearchPokemonQuerystring, IReqSearchPokemonParams } from '../../interface/IReqSearchPokemon'; |
| 147 | + |
| 148 | +export default async function ( |
| 149 | + req: FastifyRequest<{ Querystring: IReqSearchPokemonQuerystring; Params: IReqSearchPokemonParams }>, |
| 150 | +) { |
| 151 | + console.debug(req.query); |
| 152 | + console.debug(req.body); |
| 153 | + |
| 154 | + return 'hello'; |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +You have to `non-named export` (aka default export). Also you can use arrow function and you can use any name under TypeScript function name rule, as well as type arguments perfectly applied on route configuration |
| 159 | + |
| 160 | +### Variable in Route Path |
| 161 | + |
| 162 | +File or Directory name surrounded square bracket like that, |
| 163 | + |
| 164 | +```text |
| 165 | +handlers/ |
| 166 | +├─ get/ |
| 167 | +│ ├─ hero/ |
| 168 | +│ │ ├─ [name].ts |
| 169 | +``` |
| 170 | + |
| 171 | +Complex variable, No problem. |
| 172 | + |
| 173 | +```text |
| 174 | +handlers/ |
| 175 | +├─ get/ |
| 176 | +│ ├─ hero/ |
| 177 | +│ │ ├─ [affiliation]-[name].ts |
| 178 | +``` |
| 179 | + |
| 180 | +This route path access like that: `curl http://localhost:8080/hero/marvel-ironman` |
| 181 | + |
| 182 | +That's it. `fast-maker` takes care of the rest. |
| 183 | + |
| 184 | +## Example using fastify.js |
| 185 | + |
| 186 | +A complete example of using `fast-maker` can be found at [Ma-eum](https://github.com/maeumjs/maeum). |
| 187 | + |
| 188 | +## Relate To |
| 189 | + |
| 190 | +- [ts-morph](https://github.com/dsherret/ts-morph) |
| 191 | + - TypeScript Compiler API wrapper |
| 192 | + |
| 193 | +## Roadmaps |
| 194 | + |
| 195 | +- [ ] display each route path in cli-table |
| 196 | +- [ ] add new option silent |
| 197 | +- [ ] documentation site |
| 198 | +- [ ] add more test |
| 199 | + |
| 200 | +## License |
| 201 | + |
| 202 | +This software is licensed under the [MIT](https://github.com/imjuni/fast-maker/blob/master/LICENSE). |
0 commit comments