/ Server

How to build server side Swift applications?

Learn about server side Swift APIs, how to make a HTTP server with Kitura 2 hosted on linux using nginx and some daemons.

UPDATE (2018.03.20): SwiftNIO is here, you should learn Vapor instead of Kitura, but please go and read the whole new server side framework story, or scroll down below the penguin if you want to learn about how to host your Swift app.

TL;DR: as always, you can download the complete kit API and the finished source code for the servier application from theswiftdev's github page.

Native Swift server APIs

The main purpose of the native Swift server APIs project is to provide cross platform, portable basic foundation of server side networking (low level, socket base), including security and encryption features (for SSL/TLS based secure transport) plus HTTP and websocket service support.

The really first release came out on the 2nd of October, 2017 which is not aimed for production usage, but it demonstrates the basic concept about how the APIs will work in the future. If you want to learn more about it, you should definitely go and read this HTTP server tutorial by Helge who is by the way also the author of the Noze.io framework. More on that later. 🤓

As you might have noticed, the Swift server API is a fundamental toolkit, not a full featured web framework. That's why I would not recommend it for beginners, because you'll have to deal to much with all the low level stuff by yourself. If you want to learn how to write your own web framework, you should read this little microexpress article. I'd recommend to pick a framework that provides you a higher level of abstraction.

My favorite one right now is Kitura by IBM.

What about the others?

The problem with frameworks and libraries is that you have to maintain them. Many of the other "big names" have fallen because of the lack of support. If you look at the server side landscape you'll see that only few of the frameworks are properly updated. This is why I bet on Kitura, because it's an IBM product.

Perfect · Vapor · Zewo · NozeIO

Perfect is a fast, efficient, robost web framework, but for me it feels like a seven-headed beast (in my opinion it's already too complex). It has a wide community, an un-google-able (or SEO genius? 🤔) name and it's not on my list of favorites.

Vapor's concept (and syntax) is a little bit strange for me, but they made some really amazing stuff for the community. I've never liked the web framework itself too much, but I was using some Swift Packages from Vapor. You should give a try for the 3.0 version if you are going to play around with it.

Zewo had good memory management, but it was slow based on these really-really old benchmarks from the past. Note that I've never actually tried out Zewo, but sadly I won't recommend it for you because it's rarely updated.

Noze.io was a really nice attempt to make Swift backend sexy for node.js developers. The only problem is that it was maintained only by a few people, so it was eventually abandoned or at least it's having a deep sleep. I've used it for some of my sideprojects and I really liked it, but I'm not saying that you should use it too. 😴


This is a short list of other server side frameworks I've found around github, feel free to check them out, but they are rather for educational purposes than real world use.

As you can see, the only true way - based on my current experiments - to develop server side Swift applications is using the Kitura framework. It's going to be supported for a long time and the creators are working closely with Apple on the server side API foundation to make the world a better place. 😜

UPDATE (2018.03.20): SwiftNIO is here, you should learn Vapor instead of Kitura, but please go and read the whole new server side framework story.


Kitura is a free and open-source web framework written in Swift, developed by IBM and licensed under Apache 2.0. It’s an HTTP server and web framework for writing Swift server applications.

Honestly about two years ago I was not satisfied with Kitura at all. The setup process was a pain in the ass, but as of version 2.0 I can say that it's a mature and especially well-written backend framework, with an amazing idea. 😉

Codable router

Kitura 2.0 offers you the powerful Codable routing option. Which means, that if you are building a REST API, you can take advantage of sharing your Swift backend models with your client side Swift applications. There are lots of tutorials on the official website how to use the Kitura framework and build a todo app, a Swift blog, web applications or basically anything that you can imagine on the server side. 😎

Just another quick Kitura tutorial

I'd like to show you how to share code between your backend application and the frontend. We are going to make a really simple todo list example, because that's quite a popular use case. 😅

The interesting part is hosting, but now let's create our Todo infrastructure first. Start by creating two separate Swift packages using the Swift Package Manager. If you don't know how to use it, you should read my SPM tutorial.

mkdir TodoKit && cd "$_"
swift package init

TodoKit is going to be shared between the server and the frontend apps, and it will only contain the models. You can ship it on the backend side via the SPM and you can use Carthage to integrate it for the frontend apps.

import Foundation

public struct TodoObject: Codable {

    public let text: String
    public let isCompleted: Bool

    public init(text: String, isCompleted: Bool = false) {
        self.text = text
        self.isCompleted = isCompleted

That's it, now you just have to git commit all your changes and you're ready to use the TodoKit library. You can check the final code on github. Let's make a REST server.

mkdir TodoServer && cd "$_"
swift package init --type=executable

I'll skip some additional components and focus only on the routing part, you can always get the full source from github, but I don't want to embedd that much here.

guard CommandLine.arguments.count > 1, let port = Int(CommandLine.arguments[1]) else {
    print("You have to specify a valid port number as an argument.")

let router = Router()
let handler = TodoRouteHandler()

router.all(middleware: AllRemoteOriginMiddleware())
router.all(middleware: ContentTypeMiddleware())

router.get("/", handler: handler.hello)
router.get("/all", handler: handler.getAll)
router.get("/one", handler: handler.getOne)

Kitura.addHTTPServer(onPort: port, with: router)

So this is the basic HTTP server setup, we are going to listen on an incoming port, and use a router to handle all the incoming requests with the help of Codable routes. This means, that you can simply wire your Swift Codable objects into the completion handlers, no extra JSON parsing is needed at all.

import TodoKit

class TodoRouteHandler {

    func getAll(completion: ([TodoObject]?, RequestError?) -> Void) {
        let objects = [
            TodoObject(text: "first task"),
            TodoObject(text: "second task"),
        completion(objects, nil)

    func getOne(id: String, completion: (TodoObject?, RequestError?) -> Void ) {
        let object = TodoObject(text: "a task with an id: \(id)")
        completion(object, nil)

    func hello(request: RouterRequest, response: RouterResponse, next: @escaping () -> Void) {
        response.send("Hello world!")

Run the example code with the swift run TodoServer 8080 command. That's it. 😊

Hosting your app

First of all, you'll need a linux machine. You can also use a macOS server, but that'd be much more expensive. I'd recommend Amazon EC2, because the first year is free (will be enough for playing around), it's a fast, reliable, scalable hosting solution. You can fire it up in about 5 minutes with an ubuntu server. T2.nano FTW!!! 😎


Okay, let's say you've managed to get a linux machine and compiled your app on it. Whats next? First of all, if your application server needs to run constatly. If it crashes it'll stop running. This is the reason why we need to daemonize it! 👹👹👹

Systemctl upstart proces

There is a great tutorial about how to setup upstart script and respawn process, I'll just make a quick walkthrough about what you should do. First, simply create a new file under /lib/systemd/system/todo.service with the following contents.

Description=Todo server daemon

ExecStart=/usr/local/bin/todo.server 8080


Of course provide your own configuration (path, user, group and exec command). When you finish you have to reload systemctl configs, and you are ready to go.

chmod +x /lib/systemd/system/todo.service
systemctl daemon-reload
systemctl enable todo.service
systemctl start todo
systemctl status todo

From now on you can simply sudo service todo start|stop|restart your backend application server, which is actually very convenient! 🤤

Hosting through a web server


Nginx is a web server and even more. You can simply install it by running the sudo apt-get install nginx command. Maybe the hardest part is to setup a proper nginx configuration for your application server with HTTP2 and SSL support. A very basic HTTP nginx configuration should look something like this.

server {
    listen 80;
    server_name mytododomain.com;
    location / {
        proxy_pass              http://localhost:8080;
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_read_timeout      90;

This setup (somewhere inside /etc/nginx/sites-available/mytododomain.com) simply proxies the incoming traffic from the domain to the local port through pure HTTP without the S-ecurity. Don't forget to symlink the file into the sites-enabled folder and sudo service reload nginx. If you messed up someting you can always sudo nginx -t.



In order to support secure HTTP connections, first you'll need an SSL certificate. Letsencrypt will help you get one for FREE. You just have to install certbot.

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx 

You can request a new certificate and setup SSL automatically for your nginx configuration, by running the following command.

sudo certbot --nginx

You just have to follow the instructions and enjoy the brand new secure API service written in Swift language. Ah, don't forget to set up a cron job to renew your certificate periodically. sudo certbot renew --dry-run 🤓

The SSL Labs test

So far so good. You can check the strenght of your server configuration at ssllabs.com. They are going to measure how secure is your server. By default letsencrypt will give you an A result, which is perfectly fine, but you can aim for an A+ grade if you want.

In the past things were complicated. Now with letsencrypt and certbot it's really easy to make a proper setup, you don't even have to know what is a DH param. However if you want to max out the SSL labs test, more links about the topic are down below.

App Transport Security

App Transport Security (ATS) was introduced to make mobile apps more secure.
It enforces developers to talk only through secure HTTPS channels to your backend server. You can always disable ATS, but instead of hacking the system you should switch to a more secure model.

Remember HTTP is a cleartext protocol, so basically everyone can read your network traffic. Apple says all data is sensitive - they are damn right about that - and using a secure channel will give you benefits like encryption, confidentiality, integrity, authentication and identity. 🔐 ☁️ ✅

Tracking down certificate issues

The first thing that you can do is to enable CFNetwork Diagnostic Logging inside your iOS application. Now your network requests will log more information to the console.

You can also check your server from terminal with the nscurl or openssl commands.

nscurl --ats-diagnostics http://example.com/api/endpoint
openssl s_client -connect example.com:443

External sources