1- Hatsy
2- =====
1+ # Hatsy
2+
33** Asynchronous TypeScript-friendly HTTP server for Node.js**
44
55[ ![ NPM] [ npm-image ]] [ npm-url ]
@@ -22,56 +22,59 @@ Hatsy
2222[ api-docs-image ] : https://img.shields.io/static/v1?logo=typescript&label=API&message=docs&color=informational
2323[ api-docs-url ] : https://hatsyjs.github.io/hatsy/
2424
25-
26- Example
27- -------
25+ ## Example
2826
2927``` typescript
3028import { escapeHTML } from ' @frontmeans/httongue' ;
3129import { httpListener , Rendering } from ' @hatsy/hatsy' ;
3230import { dispatchByName , Routing } from ' @hatsy/router' ;
3331import { createServer } from ' http' ;
3432
35- const server = createServer (httpListener (
36- Routing
37- .and (Rendering )
38- .for (dispatchByName ({
39- hello({ route : { url : { searchParams } }, renderHtml }) {
40- renderHtml (
41- ` <!DOCTYPE html>
33+ const server = createServer (
34+ httpListener (
35+ Routing .and (Rendering ).for (
36+ dispatchByName ({
37+ hello({
38+ route : {
39+ url : { searchParams },
40+ },
41+ renderHtml ,
42+ }) {
43+ renderHtml (
44+ ` <!DOCTYPE html>
4245<html lang="en">
4346<body>Hello, ${escapeHTML (searchParams .get (' name' ) || ' World' )}!</body>
4447</html>
45- `
46- );
47- },
48- })),
49- ));
48+ ` ,
49+ );
50+ },
51+ }),
52+ ),
53+ ),
54+ );
5055
5156server .listen (8080 );
5257```
5358
5459The server above responds with ` Hello, your-name-here! ` HTML at http://localhost:8080/hello?name=your-name-here
5560
56-
57- Goals
58- -----
61+ ## Goals
5962
6063Hatsy is developed with the following goals in mind:
6164
6265- Simple API.
6366
64- Hatsy is a thin layer atop of Node.js HTTP listener.
67+ Hatsy is a thin layer atop of Node.js HTTP listener.
6568 Everything in Hatsy implemented as a [ RequestHandler] function.
6669 There is no API like application, middleware, etc. They all can be boiled down to handlers.
67-
70+
6871 More than that, Hatsy is not strictly bound to Node.js API. The core functionality works with any type of requests.
6972
7073- First-class TypeScript support.
7174
7275 No need in declaration merging.
7376 The request context can be extended in a type-safe manner when needed.
74-
77+
7578- Asynchronous processing.
7679
7780 A [ RequestHandler] can be either synchronous or asynchronous.
@@ -88,16 +91,13 @@ Non-goals:
8891
8992 The typical place of Node.js-driven HTTP server is behind the forwarding proxy. So, there is no need in these
9093 technologies supported at Node.js application level.
91-
92- Such support is still possible however. Everything that works with standard HTTP API will work with TLS or HTTP/2
93- compatibility API. Specific functionality can be added by extending a request context.
94-
9594
96- [ Connect ] : https://github.com/senchalabs/connect
95+ Such support is still possible however. Everything that works with standard HTTP API will work with TLS or HTTP/2
96+ compatibility API. Specific functionality can be added by extending a request context.
9797
98+ [ connect ] : https://github.com/senchalabs/connect
9899
99- HTTP listener
100- -------------
100+ ## HTTP listener
101101
102102` httpListener([config,] handler) ` function creates a Node.js HTTP listener. It accepts an optional configuration and
103103a [ RequestHandler] to process HTTP requests by.
@@ -120,16 +120,13 @@ a [RequestHandler] to process HTTP requests by.
120120
121121 This can be used e.g. to set up additional request processing capabilities, such as [ Logging] .
122122
123+ [ http processing configuration ] : https://hatsyjs.github.io/hatsy/interfaces/_hatsy_hatsy.HttpConfig.html
124+ [ httperror ] : https://hatsyjs.github.io/hatsy/classes/_hatsy_hatsy.HttpError.html
125+ [ logging ] : https://hatsyjs.github.io/hatsy/interfaces/_hatsy_hatsy.Logging.html
123126
124- [ HTTP processing configuration ] : https://hatsyjs.github.io/hatsy/interfaces/_hatsy_hatsy.HttpConfig.html
125- [ HttpError] : https://hatsyjs.github.io/hatsy/classes/_hatsy_hatsy.HttpError.html
126- [ Logging ] : https://hatsyjs.github.io/hatsy/interfaces/_hatsy_hatsy.Logging.html
127-
127+ ## Request Handlers
128128
129- Request Handlers
130- ----------------
131-
132- [ RequestHandler ] : #request-handlers
129+ [ requesthandler ] : #request-handlers
133130
134131Everything in Hatsy is implemented as a request handler, which is a function accepting a [ RequestContext] as its only
135132parameter. The latter contains all means necessary for request processing.
@@ -141,10 +138,9 @@ The handler can do the following:
141138- Delegate request processing to another handler by calling ` next() ` function from request context.
142139- Modify or even extend with additional properties the request context for the next handler.
143140
144-
145141### Request Context
146142
147- [ RequestContext ] : #request-context
143+ [ requestcontext ] : #request-context
148144
149145By default, HTTP request processing context contains the following properties:
150146
@@ -160,7 +156,7 @@ import { HttpMeans, RequestContext } from '@hatsy/hatsy';
160156
161157/**
162158 * This is an extended request processing means containing user info.
163- *
159+ *
164160 * They are applied by [contentExtender] handler and passed to [greeter] one.
165161 */
166162interface UserMeans {
@@ -173,8 +169,8 @@ interface UserMeans {
173169 * Delegates to [greeter] handler and extends its context with the necessary means.
174170 */
175171async function contextExtender(
176- // Every context property, including methods, is suitable for destructuring.
177- { requestAddresses , next }: RequestContext <HttpMeans >,
172+ // Every context property, including methods, is suitable for destructuring.
173+ { requestAddresses , next }: RequestContext <HttpMeans >,
178174): Promise <void > {
179175 // The second parameter contains request context properties that will be added or updated.
180176 // The rest remain unchanged.
@@ -192,9 +188,7 @@ function greeter({ name, response }: RequestContext<HttpMeans & UserMeans>): voi
192188}
193189```
194190
195-
196- Capabilities
197- ------------
191+ ## Capabilities
198192
199193Request handlers are everything needed to process the requests. However, it is quite typical to add more request
200194processing means. The request processing capabilities is a conventional API for the task. They also can be combined
@@ -211,7 +205,7 @@ Some capabilities are:
211205 Decodes ` application/x-www-form-urlecoded ` request.
212206 Extends request context with ` RequestBodyMeans ` containing ` body ` property with request body decoded as
213207 ` URLSearchParams ` or converted to some other representation.
214-
208+
215209- ` JsonParsing `
216210
217211 Parses ` application/json ` request.
@@ -228,23 +222,19 @@ Some capabilities are:
228222 Initiates routing.
229223 Extends request context with ` RouterMeans ` containing request route used to dispatch to handler(s) matching it.
230224
231-
232225See the [ very first example] containing capabilities usage. Here is the explanation:
233226
234227``` typescript
235- Routing
236- .and (Rendering ) // Combine two capabilities. `Rendering` will be applied after `Routing`.
237- // More capabilities can be combined by chaining `.and()` calls.
238- .for (handler ) // Apply capabilities to the handler.
239- // The handler receives a request context extended by both of them.
228+ Routing .and (Rendering ) // Combine two capabilities. `Rendering` will be applied after `Routing`.
229+ // More capabilities can be combined by chaining `.and()` calls.
230+ .for (handler ); // Apply capabilities to the handler.
231+ // The handler receives a request context extended by both of them.
240232```
241233
242234[ very first example ] : #example
243235[ @hatsy/router ] : https://www.npmjs.com/package/@hatsy/router
244236
245-
246- Dispatchers
247- -----------
237+ ## Dispatchers
248238
249239Dispatchers are handlers that delegate processing to other handlers depending on request.
250240
@@ -253,20 +243,17 @@ The following dispatcher implemented:
253243- [ dispatchByAccepted] dispatches accordingly to [ content negotiation] based on [ Accept] request header.
254244- [ dispatchByLanguage] dispatches accordingly to [ content negotiation] based on [ Accept-Language] request header.
255245- [ dispatchByMethod] dispatches accordingly to HTTP request method.
256- - [ dispatchError] dispatches request processing error.
246+ - [ dispatchError] dispatches request processing error.
257247
258- [ dispatchByAccepted ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy.html#dispatchByAccepted
259- [ dispatchByLanguage ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy.html#dispatchByLanguage
260- [ dispatchByMethod ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy.html#dispatchByMethod
261- [ dispatchError ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy_core.html#dispatchError
262-
248+ [ dispatchbyaccepted ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy.html#dispatchByAccepted
249+ [ dispatchbylanguage ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy.html#dispatchByLanguage
250+ [ dispatchbymethod ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy.html#dispatchByMethod
251+ [ dispatcherror ] : https://hatsyjs.github.io/hatsy/modules/_hatsy_hatsy_core.html#dispatchError
263252[ content negotiation ] : https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
264- [ Accept ] : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept
265- [ Accept-Language] : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
266-
253+ [ accept ] : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept
254+ [ accept-language ] : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
267255
268- Middleware
269- ----------
256+ ## Middleware
270257
271258[ Connect] -style middleware can be utilized by [ middleware] function.
272259
0 commit comments