If you’re a user looking to take full advantage of the type system in your Node web servers, I’ve been working on something that may be of interest to you: , a wrapper for the web server library to provide more type safety in our request handler functions. By ensuring type safety of the request and response, we can avoid many common bugs. TypeScript express-fp Express Although I am actively using this on personal projects, this is very much still WIP. There is no real documentation, although if you’re tempted to give it a go, the static types and the example should be enough to give you the gist and get you started. The current API very closely mirrors the (specifically Scala Play), because Play is a good example of a type safe web server, and it’s the only well-typed web server I’m currently familiar with. Play framework With that out of the way, let’s look at a few of the things express-fp attempts to improve. Instead of mutating responses, return responses as data In Express, responses are constructed by mutating the response object, and calling when you're done. If you forget to call , your request will hang until it timeouts. res.send res.send In express-fp, responses must be returned as object (using ). If you forget to return, or if you return the wrong type, the type system will complain. express-result-types Instead of middleware and mutation, compose pure functions In Express, requests are handled through a series of user-defined “middlewares”, which traditionally mutate the request and response objects. A common source of bugs is when middleware appear in the wrong order. For example, B assumes that A is called first and that the response has already had its response headers set. However, we can easily break this ordering, and we will get no warning from the type system about this. Common use cases for middleware include: parsing of request body and query exception handling In express-fp, middleware are replaced with function composition. Requests never fall through multiple handlers, and there is no function. next By composing pure functions, the type system is fully aware of all inputs and outputs, guaranteeing correct order. Parsing is optionally handled within request handlers, as and when needed. Thanks to pure functions, we don’t need exception handlers. Where errors are needed, we can use to return them as values. Either Validation of incoming values for type safety (request body, query) In Express, the request body and query can be anything. We can easily assert the type, e.g. , but that doesn't help validate the type at runtime— can truly be anything at runtime. req.body as MyBody req.body express-fp uses the fantastic to validate values coming into your application from outside. If you’ve used before, is similar, except it works out of the box with TypeScript. Once a value is validated, will automatically annotate the value with its static type. io-ts Joi io-ts io-ts In express-fp, we can only access the request body by defining a “runtime type” for validation. In return, we get back an type— containing validation errors or the validated body. If the body is valid, of the body, without having to repeat it in a separate type interface. Either either the type system will already know the shape In express-fp, the request query is exposed as , which matches the well-defined shape of URL query parameters. It is up to you to extract and validate query parameters. Map<string, string | string[]> Conclusion To see all of these features in combination, check out the . You can find the repository on at . example GitHub OliverJAsh/express-fp My primary motivation for this blog post is to get some feedback, so if you’re tempted, please give it a try and let me know what you think. If you do have any thoughts, please reach out to me in the comments, , or via . Further down the road I hope to write a more in-depth article with inline examples. on Twitter GitHub issues
Share Your Thoughts