Handlers
A handler is a function that recieves a Context object and return a response.
As in previous examples, handlers can return anything that is supported by the Response constructor.
app.get('/', () => 'Hi');
The handler can access the Context object, which contains the original request object and response options.
app.get('/', (c) => { c.status = 201; // Set status code. Default value is 200 c.statusText = 'Hi'; // Set status text c.headers.push(['Server', 'Mapl']); // Add a header pair console.log(c.req.headers); // Log request headers return 'Hi';});
// Context always comes after the special argument of the functionapp.get('/:user/name', (user, c) => { c.headers.push(['Server', 'Mapl']); return user;});
Note that response headers are stored as key-value pairs in an array.
Why store headers in an array instead of an object?
To have multiple header values, the headers need to be appended later to the Headers object of the final Response, which is much slower than arrays and objects as Headers has to do additional operations to normalize the header key and value on insertion.
Furthermore, JS engines often create internal structures for optimizing property accesses, which leads to more memory being used compared to arrays.
Why does context always comes after the special argument of the handler function?
These special arguments are likely to be used than the Context object so putting them as the first argument allows for an optimization when only that special argument is used.
I was thinking about attaching them to the Context object but that will make it slower, uses more memory and disallow the optimization mentioned above as you have to create a full context with that special argument value attached to it.
Mapl also includes handlers to send different types of data.
-
To return HTML directly without appending headers:
app.get('/page/*', (link) => `<p>${link}</p>`, { type: 'html' });This is faster than writing it using normal handlers (try benchmarking it yourself :]).
-
To return JSON directly without appending headers:
app.get('/info/*',(info) => ({name: info,id: Math.random()}),{ type: 'json' });This is also faster than writing it using normal handlers, as it uses the same optimization as HTML handlers.
If the handler function returns a Promise object,
it must be marked as an async
function for the compiler to detect and generate correct code.