Server side swift has been an exciting prospect ever since Apple officially released an open source linux compatible version. My curiosity finally got the better of me and it was time to give it a try.
I haven’t had any backend experience aside from a few BaaS providers, but thankfully the open source community has already been hard at work building libraries. I spent some time with several of them before deciding on Vapor by Tanner Nelson. It was the most straight forward setup, it was well suited to my task, and it specified Heroku in the docs. I picked Heroku because that’s what our backend team uses, and it has a pretty user friendly front end.
Going forward, if you’re going to follow along, you’ll need a Heroku account and an install of the Swift Development Snapshot. At the time of writing, the swift package manager isn’t included in the release, you’ll need to download the development snapshot to utilize this stuff.
The goal was to get a simple swift server up and running on Heroku, that could say hello. Having never worked in a linux environment, it made sense to start off locally. This meant setting up a local Xcode project and configuring it to run with the swift package manager. This involves 4 main steps:
Move main.swift file to Sources folder in top level directory
Add Package.swift file
Add .build directory to import paths
To get code completion and syntax highlighting with our imported libraries, the swift package manager build directory needs to be added to the import paths. Make sure to import the debug folder for the debug configuration and release for release.
Run Xcode from toolchain
If you’re on Xcode 7.3, you can also go to Xcode > Toolchains to open an instance of Xcode that utilizes a swift snapshot. It’s important to note that even with these additions, we are still unable to build within Xcode. To compile we have to use swift build from the command line.
Creating the Server
I was pleasantly surprised by how few lines of code I had to write to get a proof of concept up and running. In fewer than 10 lines of code, I was up and running.
From there it’s a one line command on the terminal to get up and running
Things are looking good so far, but let’s check it in a browser. The response on your screen might look a little different, I use this json formatter plugin.
To The Cloud
Things were pretty smooth getting setup locally, but it’s way cooler to hit a remote endpoint. I was eager to get the app up into the proverbial cloud. This was really uncharted territory for me starting out, luckily I was given some awesome guidance from Vincent Toms as we figured a lot of this out.
Heroku setup was a surprisingly pleasant experience, and in a few moments, I had a Heroku app setup, my toolbelt was installed, and I was ready to push up my project.
One of many failures of the day. I anticipated it couldn’t be that easy, so I went back to the Vapor docs and eventually landed on these newfangled things called buildpacks. Heroku provides some standard buildpacks out of the box, but doesn’t yet have anything for Swift. Yet again, the amazing open source community comes to the rescue, this time in the form of Kyle Fuller’s buildpack. Getting it integrated was simple.
With the buildpack setup, the app loaded successfully, and it was time to visit the real world url.
It couldn’t have been that easy, could it? After a bit of googling and a closer look at some examples I found out that I need a Procfile. Based on the contents, the intent of the file is pretty clear.
The buildpack was creating the executable, but Heroku didn’t know about it. With the Procfile we’re able to tell Heroku to run the SwiftServerIO executable. Time to push up the Procfile.
More Failure Pt. 2
The 2 minutes for Heroku to build seemed like forever, and I quickly reloaded my browser only to find more of this.
I thought maybe Heroku takes a few minutes to get started (it doesn’t), so I waited a while before realizing something was still not working. The executable was up, the process file was ready, but something was still off. Another round of googling commenced until I eventually ended up learning that you need to scale up the app. This involves a simple command to the Heroku toolbelt.
heroku ps:scale web=1
Heroku only gives you one dyno for free, but that’s plenty for our simple server. With that, the dynos are officially running. Time to check the browser again.
It worked! The server was up and running with the ubiquitous hello world! After a copious round of self congratulation and celebration, it was time to say hello.
Making the server say hello more personally involved a small addition to our main.swift file. By adding another get route that takes a slug, the server can use that input to say hello back.
Everything should still work, but given the usual nature of development, I prepared myself for another round of errors. The change was committed, and it was time to push it back up to Heroku.
The configurations stood the test of time and adding to my hello server was as simple as pushing up to Heroku. After a minute or so build time, the url was active and the server was saying hello. Check it out yourself.
If what I’ve seen so far is any indication, there’s going to be a strong effort from the community to add tons of support for server side swift. For me, getting real JSON from a live remote endpoint was an exciting first step into this world, and I can’t wait to see what comes next.
You can checkout the source code with nicely spaced commits here.
There’s also a Journal folder in the directory with step by step instructions included.