Summary — Using Swift as a backend language at this stage is an interesting learning experience and well-suited to a project of this small size. With some work, we’ve been able to build out a very comfortable development experience. Lack of code sharing between the backend and client is the biggest blocker we see for using Swift for bigger web projects.
Swift is a general-purpose programming language that has risen to popularity since its release in 2014. Swift is traditionally associated with iOS development but, as an open source language with Linux support, it‘s becoming an attractive language for systems tasks too. Swift as a web server has become a viable option, with frameworks such as Kitura and Vapor entering the scene. More recently, the Server APIs work group pushed out the first version of the HTTP APIs as part of the Swift open source project.
Whilst I’m biased as one of the stronger proponents of Swift in our team, we’d come to appreciate the elegance of Swift, its core libraries and the good design it encourages.
As with all HaC projects, part of the goal of this website is for contributors to learn something new and have some fun. We knew most any contributor could learn more about the state of server-side Swift and we were pretty sure we were going to have some fun with this.
As server-side Swift is in its infancy, we saw an opportunity to play with something that not many people have played with. We have run into bugs and limitations of Swift along the way and while this is at the very least a learning experience for us, we hope that we can contribute some of our learning and solutions to the community.
It was clear from the beginning that we had big ambitions for this little project. We had dozens of concepts for what we could do with it.
Swift is a general-purpose language with a relatively expressive static type system and some really natural-feeling data modelling features. It has been designed from the ground up with modern programming in mind. It combines many emerging patterns and features from other programming languages such as optionals, generics and powerful enumerations whilst leading the industry with its opinions on protocol-oriented programming.
Swift gives us the power to quickly write readable implementations of our bags full of feature ideas.
Lack of Code sharing
What this means in practice is that we either reimplement some functionality on both the backend and frontend for the sake of interactivity (e.g. Form validation) or we sacrifice interactivity for the sake of keeping code in one place. Neither is a particularly satisfying solution.
- Cross platform support (there are some discrepencies between macOS and Linux Swift behaviour)
- Interaction with
- Fast continuous deployment (our deployments using existing Heroku Buildpacks take >10 minutes)
- Mature web frameworks (there’s still a lot of work to be done even in the most popular offerings)
- Stable package management
- Nice front-end development experience (see below!)
- Typesafe templating (see below!)
It was common to find libraries that did what we wanted but that only catered to iOS/macOS. More and more cross-platforms packages are being made available and you can browse these using IBM’s ad-hoc package catalog (UPDATE Jan 18: Package Catalog has been deprecated).
With all that said, we decided that, for us and for this project, the downsides here were merely interesting hurdles and that we were going to run with Swift on the backend.
What we’ve done so far
An ergonomic development environment
Swift hasn’t stopped us from using all the tools we know and love from a ‘normal’ web development setup. To go from nothing to having the website built and loaded on your machine is as easy as:
$ git clone https://github.com/hackersatcambridge/hac-website
$ cd hac-website
$ docker-compose up
$ open http://localhost:3000
We use Gulp to watch for changes to our Swift files, rebuild the site, and reload the browser.
We spit out the build errors on the page itself so we don’t have to go fishing in the console for error messages.
Check out our gulpfile to see how we got this working.
A Type-safe HTML Builder
Whilst we were enjoying the benefits of a static type system for the internal logic of our website, when it came to display logic we were turning to Stencil. Stencil is a templating language for Swift that allows you to pass a roughly HTML-like template and a pile of values to the renderer and it will either spit out a rendered page or a nasty error. We were breaking these templates all the time. What’s more, without a statically defined interface to these templates it was difficult to reuse them in any robust manner.
Towards solving this problem, we’re experimenting with making a Swift HTML Builder that allows us to create type-safe templates. Here’s a real-world example of what writing a View Model in this system looks like:
We’ll be discussing this system, what it does, and why it’s beneficial in much more detail in the future.
Of course, a trade-off exists between having fun and building something to last. As a student society website, this is never going to be a large-scale system but it is one that needs to survive many handovers to new teams. Although it’d be unreasonable to expect many of our potential contributors to have significant server-side Swift experience, and we will stop short of recommending Swift for any large-scale web project for now, I think this project is a good place for exposing new technologies to contributors.
I’ve never had as much fun working on a website as I am with this stack. The use of Swift along with our (loose) MVVM pattern, a statically-typed HTML builder and adherence to a BEM CSS pattern has made for what I consider a very sober development experience and a wonderfully modular structure. The lessons I’ve learnt from this setup are ones that I’ll carry with me to future projects and ones that I look forward to sharing with contributors to the website.