đ“¶Express

Looks like more and more people are looking into ”Express in search for a small, approachable and Express like, SwiftNIO API. Yet ”Express was “just” intended as a tutorial on how to create a tiny web framework on top of NIO, not as a standalone library. Should we do đ“¶Express?

There are quite a few well known server side Swift frameworks, for example Kitura by IBM. Those tend to be pretty big, feature rich and very Swifty - not in a bad way, just in a “different” way. There is nothing wrong with that, and we encourage you to look into those!
However, some people are just looking for a quick way to do Node/Express, but using Swift. Nothing fancy, just something for doing quick and easy endpoints, but in a more resource efficient, scalable and reliable way.

As demonstrated by Noze.io and ”Express, Swift can look almost exactly like JavaScript Node code:

import http

http.createServer { req, res in 
  res.writeHead(200, [ "Content-Type": "text/html" ])
  res.end("<h1>Hello World</h1>")
}
.listen(1337)

Right now the Always Right Institute is providing three solutions for doing Express-like, server side Swift:

Noze.io

Noze.io provides two core features: a Node/Express like API (see above), and type-safe back-pressure aware pull-streams. It is built on top of the async I/O provided by libdispatch.

It is however, pretty slow 🐌 That has various reasons and is partially due to being started in the Swift 2 timeframe.
The plan for Noze.io is to rebuild its typed pull streams on top of SwiftNIO, maybe as something like swift-nio-streams. However, there is no timeframe for that. ⏳

Summary: Not recommended for production.

ApacheExpress

ApacheExpress / mod_swift are a great way to build Swift server applications. It can exploit the proven and battle tested functionality of Apache. Any kind of authentication mechanism you can think of, rate limiting / anti-DoS modules, or mod_ssl, mod_h2 for HTTP/2 support, etc.
Using ZeeQL you can even access databases provided by mod_db.

LoadSwiftModule ApacheMain /usr/libexec/apache2/mods_demo.so

ApacheExpress also provides a Node/Express like API derived from Noze.io. However, Apache modules operate synchronously. Depending on the scale you are operating on (are you serving hundreds of thousands of concurrent connections?), or if you have a workload which is highly I/O bound and asynchronous by nature (e.g. a proxy server), this can be an issue.

Summary: mod_swift / Apex are excellent ways to run Swift code on the server in a feature rich and rock solid way. Synchronously, though.

(There used to be a time when Apache was consider a “big” server, today the whole server is smaller than the even the Swift library you are linking against.)

”Express

Originally ”Express was “just” intended as a tutorial. It demonstrates how a tiny but very useful web framework can be trivially built on top of SwiftNIO, in a few hundred lines of code. Again, it intentionally looks a little like Express:

import MicroExpress

let app = Express()

app.get("/moo") { req, res, next in
  res.send("Muhhh")
}
app.get("/json") { _, res, _ in
  res.json([ "a": 42, "b": 1337 ])
}
app.get("/") { _, res, _ in
  res.send("Homepage")
}

app.listen(1337)

Though it was never really intended as a standalone library, people seem to start using it for realz. And even start submitting PRs 😘

(We are also using ”Express in production because it is so convenient for small things 
)

đ“¶Express?

What we should really do is Noze.io v2 based on top of NIO, but:

However, there is no timeframe for that. ⏳

So while we wait for that, should we create a đ“¶Express?

The idea of đ“¶Express would be, that it essentially becomes a thin wrapper around NIO which provides many more Node.js like APIs. Just like Noze.io v2 without the type-safe pull-streams.

The appeal here is that đ“¶Express would be a really low hanging fruit. The core could be forked off ”Express and many Express-like modules could be quickly migrated over from Noze.io and/or ApacheExpress. One example being the middleware implementation which allows nesting of routers like the real Express (”Express has just one matching level).

However that should not become a fat framework. The setup could be that of Noze.io: A set of tiny Swift modules (static libraries consumed as necessary). It could build as a standalone Xcode project suitable for being embedded in applications, and as a regular SwiftPM project at the same time.

What to people think? Is there value in having that? A small Express-like framework which is a little more than ”?

To drop your opinions, feel free to come along the Noze.io Slack, or at @noze_io đŸ€“

Written on January 10, 2019