6 ms·
Show HN: Custom Haskell handlers for Nginx
This is rather a mature project. It began out of curiosity: I wanted to test if Haskell FFI was powerful and expressive enough to interconnect C and Haskell code flawlessly. Particularly, if C strings generated inside Nginx can be shared within Haskell code and what must be done to respect their lifetimes etc.
Recently, I released version 3.2.0 with revamped README (with a lot of examples) and a new approach to building Haskell handlers using the modernized cabal v2-build for dependencies.
- greydius 3y agoI use warp to serve my projects and configure nginx as a reverse proxy. There might be a bit of overhead with this setup, but I like how simple it is.
- lyokha 3y agoThis module can be used to build smart reverse proxies, not only round-robin, or hash or app-names based. For example, you may want to lookup destinations in some distributed cache db and alike.
- icrbow 3y agoI used to wrap everything in Nginx, but `warp` can hold its own candle, with HTTP2 and stuff. One less piece to configure.
- deleted 3y ago[deleted]
- robertlagrant 3y agoOne of the things I think Python got right was the establishing of a WSGI (and, much later, ASGI) protocol to demarcate application from the reality of networks. Does Haskell have an equivalent? (Is it a monad?)
- bradrn 3y agoI don’t know much about Python, but from searching up WSGI, this sounds quite similar to the Web Application Interface [https://hackage.haskell.org/package/wai https://hackage.haskell.org/package/wai].
- robertlagrant 3y agoAh - yes. Looks exactly the same sort of thing!
- lyokha 3y agoThis is not a gateway, but you can build gateways with this. The module provides a lower-level handlers that can be divided into 4 major groups: - Synchronous tasks: enable a full-featured language in Nginx location handlers - Asynchronous tasks: Nginx worker's main thread do not block on waiting, fit very well IO-bound tasks - Asynchronous services: background tasks that are not bound to client requests - Content handlers: generate responses to client requests Note that all of them run inside the Nginx worker process, synchronous - within the main worker's thead, asynchronous - in the lightweight threads of the Haskell runtime. As to Monad and demarcation. The synchronous tasks are sub-divided into pure and impure tasks. Pure tasks are guaranteed in compile time to not launch missiles in run time. Impure tasks are wrapped inside the IO Monad and allowed to do whatever usual C code can do. Btw, guarantee of purity is not a virtue of Monad solely, but rather a more complex thing, e.g. hiding IO constructor does not let escape from IO. Besides IO, there are various effect systems in Haskell which let applying more constraints on the effects but they are not (yet?) used in this module.
- sshine 3y agoHaskell has WAI, which is similar to WSGI: https://www.snoyman.com/reveal/first-app-wai-warp https://www.snoyman.com/reveal/first-app-wai-warp
- Vosporos 3y agoNice, very nice!
- saurabhnanda 3y agoAre you using this in production? Any benchmarks?
- lyokha 3y agoYes, more than 5 years in a few components (mostly as smart reverse proxies as I said in another comment). They are high-loaded entry points on the client front, with a few hundred thousands clients. But I cannot say details due to NDA, even where it's used. I did not compare performance with other alternatives such as OpenResty. I tried, but Nginx is very immune to resist loading it well from home network :)
- hacktrem 3y ago[flagged]
- trentearl 3y agoLovely project, much more polish than I anticipated.
- mark_l_watson 3y agoI used to build web apps around nginx and this would have been very useful for me then. Still a cool and tidy looking project! I am trying to think of some practical project I could use to try this.
- archibaldJ 3y agoAw nice; I think haskell-wasm uses FFI too https://www.tweag.io/blog/2018-09-12-asterius-ffi/ https://www.tweag.io/blog/2018-09-12-asterius-ffi/ super cool to see an nginx version of it!
- lyokha 3y agoNice article, thanks for sharing this!