Swift on the Server: an introduction

This is the first post of a mini-series about Swift on the Server.

State of Play

Swift was announced at WWDC 2014 - at the time a major suprise to the entire  developer ecosystem; with the developer community in general, such as Hacker News and Reddit - particularly hopeful for it's future. One of the major announcements by Chris Lattner at the time, although maybe not immediately obvious to everyone - is that Swift was heralded as a language which could work at any level, to quote : "It's designed to scale from “hello, world” to an entire operating system".

Ever since the first beta - Swift's evolved quickly, being shaped by both people internal at  - and by the community. Initially these community proposals were in the form of Bug Reports and Tweets with the Swift engineering team - it's worth bearing in mind that this was completely unchartered territory for  at the time. In order to achieve these frequent changes without breaking things - thus-far iOS and macOS apps using Swift have shipped the Swift runtime inside of applications - meaning there was about a 7-8MB overhead per app.

Fast-forwarding to WWDC 2015 -  announced that Swift would be open-source by the end of the year - at the time people were pretty skeptical that if it were to be open-sourced at all - then it would be source-dumped on the Apple open source site. Swift went open source on Github in early December 2015 - rapidly becoming the most popular language on Github - and ported to other platforms. Today it's available on everything from Raspberry Pii's, Calculators, Android and even Windows (albeit it's early days right now).

One really nice thing of note about Swift going open-source is that it's not just a repository that's been open-sourced - but the entire language, including the Compiler, the Frameworks, the Bug List and the Change Management Process. Changes for Swift are discussed first on a mailing list, then submitted as proposals to the Swift Evolution repository - where they're discussed further and ultimately voted on; if accepted it's then assigned a language version. Be aware: this mailing list is very active - there's some apps available such as Hirundo which make consuming this simpler - if you're interested in staying up to date at this level. The result of this is that anyone can get involved at any level.

The result of all this is that Swift has a healthy developer ecosystem - with frequent releases, plenty of contributions from the community - and growing support. It's also got a number of web frameworks, and libraries available for common tooling (e.g. Mysql/Postgresql) - which is why we're here and we'll cover shortly.

Why Swift on the Server?

  • Designed for Safety
  • Performance: Swift is fast, with native compilation too
  • Pleasant language - reusable on multiple platforms
  • A ton of libraries available

Let's go through some of these in more detail:

Swift is Fast

A lot of people have talked about how fast Swift is - but very few so far have posted any results online. The two that I'd like to link too are Swift vs C++ using specific algorithms - and Swift compared to other languages specifically focused on web frameworks.

In particular I'd like to highlight the following graph from the second post - which shows the Plain Text Requests per Second (where a higher is better):

One other thing to mention is that Swift is compiled for the specific CPU that you're using - and the code can even be optimized by setting the Optimization Level at Compile Time - which can give you a nice performance boost on top.

Swift is Safe

One of the major goals when designing Swift was Type Safety - in addition to being a Statically Typed - the language is designed so that it's clear what a bit of code will do. For instance - if you've got a method which could throw an Exception, it explicitly needs to be marked as throws - with any calls to the method handled either by a try, with a relevant catch statement - so it's possible to understand the flow. Whilst some other languages like Java have a similar approach - I've found there's more friction in these languages - where you end up having to specify each exception type that could be thrown.

Another great example is the Compiler - offering warnings for things like mutable variables which aren't actually being mutated, recommending you use immutable variables unless you really need not too.

Day-to-Day Development with Swift

Swift's also a pretty nice language to write in - having integrated the best parts of many different languages and then adding their own too, such as the Guard Statement. It's pretty convenient being able to use the same language to write your backend using the same language that you'd write your iOS/macOS apps in.

There's a wide range of libraries available for things such as persistence stores - with support for MySql/Postgres/Mongo/Redis (with optional ORM support) - as well as things like Facebook/Google Authentication / SDK's and Middleware.

When you consider all of this - I believe we're now at a point where it's entirely possible to use Swift on the Server.

Swift Web Frameworks

There's two main web frameworks in Swift right now:

There's also a few others, but they've not really taken off in the same fashion:

Regardless of the language - fundamentally most modern web frameworks aitre pretty similar, generally being designed using the principles of MVC / Model View Controller - with routing and middleware thrown in for good measure. This is as true for Express.js as it is for Django, Hapi.js, ASP.NET MVC - or the Swift frameworks, Vapor and Kitura.

It's been widely publicised that IBM are investing heavily in Swift on both the client and the server; with some of the fruits of this labour visible on both the IBM-Swift Github - and the  Swift site. They've created a web framework called Kitura - it's pretty nice - with a core team inside of IBM - and the source code being developed in the open. In particular - IBM did a session at WWDC 2016 which explains some of the general architecture and covers the journey that Kitura has taken - well worth a watch. Vapor on the other hand has been created by a community, again it's also a typical modern web framework.

It's worth saying that both of these frameworks - and the entire Swift language are moving pretty fast right now, which given that Swift 3 isn't yet completely source stable - makes life a little challenging. However in order to work sanely, there's the SwiftEnv version manager created by KyleF - very similar to RubyEnv/NodeEnv - effectively this makes it possible to work against specific versions of Swift sanely by specifying the Swift version in a file (.swift-version) within the repository - and upgrade on your own timeframe.

FWIW I actually first started using Kitura - but found there were enough things that didn't feel so nice syntax-wise that I seeked out an alternative. That said it's a great framework - and be sure to check it out, it just wasn't for me at the time; given this - I'll be primarily focusing on the Vapor web framework.

Requirements

You can build for Swift using either macOS or Linux right now - and there's supported tooling for each.

Whilst you don't need Ruby - I'd highly recommend having it available, as it means we can use SwiftEnv to manage our Swift versions, rather than managing them ourselves.

With regards to an IDE - just about anything should do, the following are specific to macOS:

The following are available cross-platform:

At the end of the day - you can use what you want - but the plugins will make your life a ton simpler

Side note: at this point only macOS/Ubuntu 14/15 are supported through official builds - Ubuntu 16 (and presumably other distro's) have worked just fine for me by using both the Ubuntu build, or through compiling Swift by-hand, but YMMV

Right now neither Swift and SwiftEnv officially support Windows - however there's some limited activity in this space from the community - from what I've seen it's more of a proof-of-concept than anything usable anytime soon - but it's cool none the less. Personally my money is on Microsoft porting Swift to Windows at some point in 2017 - but let's see.

There's a nice aside here about the term "Cross Platform" - Jason Imison tweeted a while back that the term's changed meaning over the past few years, from "it runs on macOS/Linux!" - to "it supports Windows". Perhaps this is a symptom of coming from a primarily Microsoft/.net background - but it's interesting either way.

Installing SwiftEnv

SwiftEnv is a great way to handle running multiple versions of Swift side-by-side. Essentially you a version of Swift once - and then SwiftEnv handles referring to each version - either on a project-level or at a system-wide level.

To get started - let's clone the SwiftEnv repo:

git clone https://github.com/kylef/swiftenv.git ~/.swiftenv  

When that's done - we then need to ensure we active SwiftEnv at shell login:

Note: if you're running this on Linux - you'll want to change .bash_profile for .bashrc in the following examples

echo 'export SWIFTENV_ROOT="$HOME/.swiftenv"' >> ~/.bash_profile  
echo 'export PATH="$SWIFTENV_ROOT/bin:$PATH"' >> ~/.bash_profile  
echo 'eval "$(swiftenv init -)"' >> ~/.bash_profile  

In order to get access to SwiftEnv without reloading - let's then reload our bash profile:

source ~/.bash_profile  

(again: on Linux update the file name)

Installing a version of Swift

SwiftEnv works by installing one or more versions of Swift into a central place - which can then be configured as the current version of Swift either System-Wide or for a specific folder.

Let's start by installing the Swift 3.0 GM version of Swift:

swiftenv install 3.0-GM-CANDIDATE  

Once we've got this installed - we can either install this system-wide by running the following - however I'd recommend only doing this for the latest, stable version of Swift - unless you like living life on the edge.

swiftenv global 3.0-GM-CANDIDATE  

It's possible to configure a version of Swift for a specific repository/directory too - we can achieve this by running:

swiftenv local 3.0-GM-CANDIDATE  

Technically what this does is to just output the version number into a (.swift-version) file - meaning it can be checked into source-control too - which means that you can ensure everyone's using the same version :)

Installing the Vapor Toolkit

The Vapor Toolkit includes a prequesites check to ensure that you've got the correct version of Swift configured correctly. We can run this check by running:

curl -sL check.vapor.sh | bash  

an aside: I'm sure it doesn't need saying, but this doesn't have/need sudo in front of it. Don't run stuff directly off the internet as Sudo - it's a massive security risks

What this checks is that you've got both a working Swift toolchain on your path, and that you've got other common dependencies such as Git etc. It's also worth noting that if you're having issues with your environment - this Check is a great place to start.

If running this command comes back with a Cross - you'll need to fix that, so either install Git (Xcode includes this by default) - or ensure that Swift/SwiftEnv are configured correctly (it'll tell you which dependency is missing).

If this comes back with a tick - we're in a position to install the Vapor Toolkit by running:

curl -sL toolkit.vapor.sh | bash  

Once this is done - we can check that Vapor's installed correctly by running:

vapor --help  

This should come back with a list of commands available in the Vapor Toolkit - something like this:

$ vapor --help
Usage: vapor <new|build|run|fetch|clean|test|xcode|version|self|heroku|docker>  
Join our Slack if you have questions, need help,  
or want to contribute: http://slack.qutheory.io  

At this point - your environment is configured correctly for both Swift and Vapor. In the next post in the series - we'll cover getting started with Swift.