|
| 1 | +--- |
| 2 | +sidebar_position: 2 |
| 3 | +--- |
| 4 | + |
| 5 | +# http |
| 6 | + |
| 7 | +this module is used for exposing http routes for use in apis and other purposes. |
| 8 | + |
| 9 | +## concept |
| 10 | + |
| 11 | +files are organized within the `http` directory in any manner desired. a common pattern used is to have directories in the same structure that your urls will ultimately be, however, this is entirely up to you. exa.js on start will process all files recursively that are present in the `http` directory. |
| 12 | + |
| 13 | +## internal handling |
| 14 | + |
| 15 | +http server and routes and implemented using express.js, a well known and trusted http server. everything express.js supports is also supported in exa.js. |
| 16 | + |
| 17 | +## anatomy of an http file |
| 18 | + |
| 19 | +the following is the structure of an http file |
| 20 | + |
| 21 | +```js title="http/sample.js" |
| 22 | +import authorized from '#app/middleware/authorized.js'; |
| 23 | + |
| 24 | +export default new class { |
| 25 | + |
| 26 | + routes = { |
| 27 | + 'get /hello/world': 'world', |
| 28 | + } |
| 29 | + |
| 30 | + middleware = { |
| 31 | + '*': [authorized] |
| 32 | + } |
| 33 | + |
| 34 | + async world(req, res) { |
| 35 | + return res |
| 36 | + .status(200) |
| 37 | + .send({ |
| 38 | + message: 'hello world' |
| 39 | + }); |
| 40 | + } |
| 41 | + |
| 42 | +}; |
| 43 | +``` |
| 44 | + |
| 45 | +### routes |
| 46 | + |
| 47 | +each route is a key composed of the http method and route path or pattern with a string value of the name of the method it should call. because this just wraps express.js internally, it supports everything express.js supports, including: |
| 48 | + |
| 49 | +basic routes |
| 50 | +```js |
| 51 | +routes = { |
| 52 | + 'get /hello/world': 'world', |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +regex routes |
| 57 | +```js |
| 58 | +routes = { |
| 59 | + 'get /pets/(dog|cat)': 'pet', |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +param routes |
| 64 | +```js |
| 65 | +routes = { |
| 66 | + 'get /blogs/:blog_id': 'get_blog', |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +### middleware |
| 71 | + |
| 72 | +one or more pieces of middleware can be ran prior to the route method being called. this middleware is great for many purposes such as authentication, setting context variables, or performing pre-route logic. |
| 73 | + |
| 74 | +a middleware file looks like this: |
| 75 | + |
| 76 | +```js title="middleware/authorized.js" |
| 77 | +export default async (req, res, next) => { |
| 78 | + // middleware logic |
| 79 | + if (req.headers.authorization !== 'abc123') { |
| 80 | + return res |
| 81 | + .status(401) |
| 82 | + .send(); |
| 83 | + } |
| 84 | + |
| 85 | + return next(); |
| 86 | +}; |
| 87 | +``` |
| 88 | + |
| 89 | +this middleware checks an api key to see if it's the right value. if it's not, a 401 unauthorized response is received, otherwise `next()` is called which either calls the next middleware in the chain or calls the route method. |
| 90 | + |
| 91 | +to use middleware, add key/value pairs to the `middleware` object. the key should be the method name and the value should be an array of middleware to run. |
| 92 | + |
| 93 | +```js |
| 94 | +// apply authorized middleware to all routes |
| 95 | +middleware = { |
| 96 | + '*': [authorized], |
| 97 | +} |
| 98 | + |
| 99 | +// apply authorized middleware to one route |
| 100 | +middleware = { |
| 101 | + hello: [authorized], |
| 102 | +} |
| 103 | + |
| 104 | +// apply authorized middleware to all routes except for hello |
| 105 | +middleware = { |
| 106 | + '*': [authorized], |
| 107 | + hello: [] |
| 108 | +} |
| 109 | + |
| 110 | +// apply common and authorized middleware to all routes |
| 111 | +middleware = { |
| 112 | + '*': [common, authorized], |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +middleware precedence is top to bottom. this is why everything works in the third example. `hello` has a value of blank array. |
0 commit comments