|
1 | 1 | # acorn
|
2 | 2 |
|
3 |
| -[](https://github.com/oakserver/acorn) |
4 |
| - |
5 |
| -Rapidly develop and iterate on RESTful APIs using a strongly typed router |
6 |
| -designed for Deno CLI, Deno Deploy and Bun. |
7 |
| - |
8 |
| -## Usage |
9 |
| - |
10 |
| -### Under Deno runtime or Deploy |
11 |
| - |
12 |
| -Add the package to your project: |
13 |
| - |
14 |
| -``` |
15 |
| -deno add @oak/acorn |
16 |
| -``` |
17 |
| - |
18 |
| -### Under Node.js and Cloudflare Workers |
19 |
| - |
20 |
| -Install the package using your chosen package manager: |
21 |
| - |
22 |
| -#### npm |
23 |
| - |
24 |
| -``` |
25 |
| -npx jsr add @oak/acorn |
26 |
| -``` |
27 |
| - |
28 |
| -#### Yarn |
29 |
| - |
30 |
| -``` |
31 |
| -yarn dlx jsr add @oak/acorn |
32 |
| -``` |
33 |
| - |
34 |
| -#### pnpm |
35 |
| - |
36 |
| -``` |
37 |
| -pnpm dlx jsr add @oak/acorn |
38 |
| -``` |
39 |
| - |
40 |
| -### Under Bun |
41 |
| - |
42 |
| -``` |
43 |
| -bunx jsr add @oak/acorn |
44 |
| -``` |
45 |
| - |
46 |
| -### Listening |
47 |
| - |
48 |
| -For Deno, Node.js, and Bun the router needs to be configured and then start |
49 |
| -listening for requests: |
50 |
| - |
51 |
| -```ts |
52 |
| -import { Router } from "@oak/acorn"; |
53 |
| - |
54 |
| -const BOOKS = { |
55 |
| - "1": { id: 1, title: "The Hound of the Baskervilles" }, |
56 |
| - "2": { id: 2, title: "It" }, |
57 |
| -}; |
58 |
| - |
59 |
| -const router = new Router(); |
60 |
| - |
61 |
| -router.get("/", () => ({ hello: "world" })); |
62 |
| -router.get("/books/:id", (ctx) => BOOKS[ctx.params.id]); |
63 |
| - |
64 |
| -router.listen({ port: 5000 }); |
65 |
| -``` |
66 |
| - |
67 |
| -### Fetch handlers |
68 |
| - |
69 |
| -For Cloudflare Workers the router needs to be configured and router needs to be |
70 |
| -the default export: |
71 |
| - |
72 |
| -```ts |
73 |
| -import { Router } from "@oak/acorn"; |
74 |
| - |
75 |
| -const BOOKS = { |
76 |
| - "1": { id: 1, title: "The Hound of the Baskervilles" }, |
77 |
| - "2": { id: 2, title: "It" }, |
78 |
| -}; |
79 |
| - |
80 |
| -const router = new Router(); |
81 |
| - |
82 |
| -router.get("/", () => ({ hello: "world" })); |
83 |
| -router.get("/books/:id", (ctx) => BOOKS[ctx.params.id]); |
84 |
| - |
85 |
| -router.listen({ port: 5000 }); |
86 |
| - |
87 |
| -export default router; |
88 |
| -``` |
89 |
| - |
90 |
| -## Philosophy |
91 |
| - |
92 |
| -After having spent years working on [oak](https://jsr.io/@oak/oak) and extensive |
93 |
| -experience with building Deno, that really when people were looking at |
94 |
| -middleware type of solution, really what they were looking fore was a straight |
95 |
| -forward router that made it easy to handle JSON payloads. |
96 |
| - |
97 |
| -Also, oak was created in the early days of Deno, before it even had a native |
98 |
| -HTTP server, and that server supported the web standard `Request` and |
99 |
| -`Response`. |
100 |
| - |
101 |
| -Acorn was the culmination of that need. It makes it easy to have route handlers |
102 |
| -that are straight forward and focuses on staying closer to the native |
103 |
| -implementations of Deno constructs that have evolved over time. |
104 |
| - |
105 |
| -## Routes |
106 |
| - |
107 |
| -An instance of a router has several methods for registering a handler for a |
108 |
| -route. The methods correspond to one or many HTTP methods or verbs. When a |
109 |
| -request is handled by the router that matches a route and the HTTP method(s), it |
110 |
| -will invoke the registered handler. |
111 |
| - |
112 |
| -The handler is provided with a context which contains information about the |
113 |
| -request: |
114 |
| - |
115 |
| -```ts |
116 |
| -interface Context<Params extends Record<string, string>, BodyType> { |
117 |
| - readonly addr: Addr; |
118 |
| - readonly cookies: SecureCookieMap; |
119 |
| - readonly params: Params; |
120 |
| - readonly request: Request; |
121 |
| - readonly searchParams: Record<string, string>; |
122 |
| - body(): Promise<BodyType | undefined>; |
123 |
| - url(): URL; |
124 |
| -} |
125 |
| -``` |
126 |
| - |
127 |
| -The `.params` property provides any parameters (named captures) parsed out when |
128 |
| -matching the route string. |
129 |
| - |
130 |
| -The `.searchParams` property provides any search parameters associated with the |
131 |
| -request. |
132 |
| - |
133 |
| -The `.addr` property provides the remote address associated with the request. |
134 |
| - |
135 |
| -The `.url()` method returns an instance of URL associated with the request. |
136 |
| - |
137 |
| -The `.body()` method is a convenience method to deal with decoding a JSON string |
138 |
| -body. It can be used with an optional |
139 |
| -[deserializer ](https://deno.land/x/[email protected]/mod.ts?s=Deserializer) which can |
140 |
| -do advanced decoding of the body, or it will attempted to be decoded from the |
141 |
| -JSON string. |
142 |
| - |
143 |
| -More advanced request body handling can be handled via the `.request` property. |
144 |
| - |
145 |
| -The handler is then expected to have a return value which can be a `Request` |
146 |
| -instance, a value that is a [`BodyInit`](https://deno.land/api?s=BodyInit), or |
147 |
| -any other value. If an optional |
148 |
| -[serializer ](https://deno.land/x/[email protected]/mod.ts?s=Serializer) is provided |
149 |
| -and the response is not a `Request` instance or of the type `BodyInit`, the |
150 |
| -value will be passed to the serializer. If no serializer is present then |
151 |
| -[`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) |
152 |
| -will be used to attempt to convert the value to a JSON string. If `undefined` is |
153 |
| -returned, then a `404 NotFound` response will be generated. |
154 |
| - |
155 |
| -The handling of the request differs significantly from middleware solutions like |
156 |
| -[oak](https://oakserver.github.io/oak/). In most cases you will want only one |
157 |
| -handler per route and HTTP method combination. There is nothing that prevents |
158 |
| -multiple registrations, but the first handler registered that returns a non |
159 |
| -`undefined` value will be used and any remaining handlers will not be called. |
160 |
| - |
161 |
| -Underneath, the router matches route strings using the browser standard |
162 |
| -[URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) |
163 |
| -and matches the pathname part of the URL. |
| 3 | +A focused Javascript/TypeScript framework for creating RESTful services. |
164 | 4 |
|
165 | 5 | ---
|
166 | 6 |
|
|
0 commit comments