1 | :station: _**Micro Router -**_ A tiny and functional router for ZEIT's [micro](https://github.com/zeit/micro)
|
2 |
|
3 | [![GitHub release](https://img.shields.io/github/release/pedronauck/micro-router.svg)]()
|
4 | [![Build Status](https://travis-ci.org/pedronauck/micro-router.svg?branch=master)](https://travis-ci.org/pedronauck/micro-router)
|
5 | [![Coveralls](https://img.shields.io/coveralls/pedronauck/micro-router.svg)]()
|
6 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/ebdcc3e942b14363a96438b41c770b32)](https://www.codacy.com/app/pedronauck/micro-router?utm_source=github.com&utm_medium=referral&utm_content=pedronauck/micro-router&utm_campaign=Badge_Grade)
|
7 |
|
8 | ## 👌 Features
|
9 |
|
10 | * **Tiny**. Just couple lines of code.
|
11 | * **Functional**. Write your http methods using functions.
|
12 | * **Async**. Design to use with `async/await`
|
13 |
|
14 | ## 💻 Usage
|
15 |
|
16 | Install as project dependency:
|
17 |
|
18 | ```bash
|
19 | $ yarn add microrouter
|
20 | ```
|
21 |
|
22 | Then you can define your routes inside your microservice:
|
23 |
|
24 | ```js
|
25 | const { send } = require('micro')
|
26 | const { router, get } = require('microrouter')
|
27 |
|
28 | const hello = (req, res) => send(res, 200, `Hello ${req.params.who}`)
|
29 |
|
30 | const notfound = (req, res) => send(res, 404, 'Not found route')
|
31 |
|
32 | module.exports = router(get('/hello/:who', hello), get('/*', notfound))
|
33 | ```
|
34 |
|
35 | ### `async/await`
|
36 |
|
37 | You can use your handler as an async function:
|
38 |
|
39 | ```js
|
40 | const { send } = require('micro')
|
41 | const { router, get } = require('microrouter')
|
42 |
|
43 | const hello = async (req, res) =>
|
44 | send(res, 200, await Promise.resolve(`Hello ${req.params.who}`))
|
45 |
|
46 | module.exports = router(get('/hello/:who', hello))
|
47 | ```
|
48 |
|
49 | ### route methods
|
50 |
|
51 | Each route is a single basic http method that you import from `microrouter` and has the same arguments:
|
52 |
|
53 | * `get(path = String, handler = Function)`
|
54 | * `post(path = String, handler = Function)`
|
55 | * `put(path = String, handler = Function)`
|
56 | * `patch(path = String, handler = Function)`
|
57 | * `del(path = String, handler = Function)`
|
58 | * `head(path = String, handler = Function)`
|
59 | * `options(path = String, handler = Function)`
|
60 |
|
61 | #### path
|
62 |
|
63 | A simple url pattern that you can define your path. In this path you can set your parameters using a `:` notation. The `req` parameter from `handler` will return this parameters as an object.
|
64 |
|
65 | For more information about how you can define your path, see [url-pattern](https://github.com/snd/url-pattern) that's the package that we're using to match paths.
|
66 |
|
67 | #### handler
|
68 |
|
69 | The `handler` method is a simple function that will make some action base on your path.
|
70 | The format of this function is `(req, res) => {}`
|
71 |
|
72 | ##### `req.params`
|
73 |
|
74 | As you can see below, the `req` parameter has a property called `params` that represents the parameters defined in your `path`:
|
75 |
|
76 | ```js
|
77 | const { router, get } = require('microrouter')
|
78 | const request = require('some-request-lib')
|
79 |
|
80 | // service.js
|
81 | module.exports = router(
|
82 | get('/hello/:who', (req, res) => req.params)
|
83 | )
|
84 |
|
85 | // test.js
|
86 | const response = await request('/hello/World')
|
87 |
|
88 | console.log(response) // { who: 'World' }
|
89 | ```
|
90 |
|
91 | ##### `req.query`
|
92 |
|
93 | The `req` parameter also has a `query` property that represents the `queries` defined in your requision url:
|
94 |
|
95 | ```js
|
96 | const { router, get } = require('microrouter')
|
97 | const request = require('some-request-lib')
|
98 |
|
99 | // service.js
|
100 | module.exports = router(
|
101 | get('/user', (req, res) => req.query)
|
102 | )
|
103 |
|
104 | // test.js
|
105 | const response = await request('/user?id=1')
|
106 |
|
107 | console.log(response) // { id: 1 }
|
108 | ```
|
109 |
|
110 | ### Parsing Body
|
111 |
|
112 | By default, router _doens't parse anything_ from your requisition, it's just match your paths and execute a specific handler. So, if you want to parse your body requisition you can do something like that:
|
113 |
|
114 | ```js
|
115 | const { router, post } = require('microrouter')
|
116 | const { json, send } = require('micro')
|
117 | const request = require('some-request-lib')
|
118 |
|
119 | // service.js
|
120 | const user = async (req, res) => {
|
121 | const body = await json(req)
|
122 | send(res, 200, body)
|
123 | }
|
124 |
|
125 | module.exports = router(
|
126 | post('/user', user)
|
127 | )
|
128 |
|
129 | // test.js
|
130 | const body = { id: 1 }
|
131 | const response = await request.post('/user', { body })
|
132 | ```
|
133 |
|
134 | ### UrlPattern instance as path
|
135 |
|
136 | The package [url-pattern](https://github.com/snd/url-pattern) has a lot of options inside it to match url. If you has a different need for some of your paths, like make pattern from a regexp, you can pass a instance of `UrlPattern` as the path parameter:
|
137 |
|
138 | ```js
|
139 | const UrlPattern = require('url-pattern')
|
140 | const { router, get } = require('microrouter')
|
141 |
|
142 | const routes = router(
|
143 | get(
|
144 | new UrlPattern(/^\api/),
|
145 | () => 'This will match all routes that start with "api"'
|
146 | )
|
147 | )
|
148 | ```
|
149 |
|
150 | ### Namespaced Routes
|
151 |
|
152 | If you want to create nested routes, you can define a namespace for your routes using the `withNamespace` high order function:
|
153 |
|
154 | ```js
|
155 | const { withNamespace, router, get } = require('microrouter')
|
156 | const { json, send } = require('micro')
|
157 |
|
158 | const oldApi = withNamespace('/api/v1')
|
159 | const newApi = withNamespace('/api/v2')
|
160 |
|
161 | const routes = router(
|
162 | oldApi(get('/', () => 'My legacy api route')),
|
163 | newApi(get('/', () => 'My new api route'))
|
164 | )
|
165 | ```
|
166 |
|
167 | _PS: The nested routes doesn't work if you pass a UrlPattern instance as path argument!_
|
168 |
|
169 | ## 🕺 Contribute
|
170 |
|
171 | 1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
|
172 | 2. Install dependencies using Yarn: `yarn install`
|
173 | 3. Make the necessary changes and ensure that the tests are passing using `yarn test`
|
174 | 4. Send a pull request 🙌
|