Server-side Swift, how to set up a Vapor backend
I finally found the time to test server-side Swift by setting up a Vapor backend. This is something I’ve wanted to test for some time but before swift 3.0 was released it seemed a little bit too much work. Most of the frameworks were also in work in progress state which made things difficult. I chose Vapor since it has the best documentation and seems to be the most popular. Also, Ray Wenderlich is tweeting tutorials for Vapor so I think Vapor has a bright future ahead. You might also want to check Perfect, Kitura and Zewo to get a better view on the server side swift field.

 

In this tutorial, we are creating a “Friends” restful service API to which you can post details from friends, list your current friends, update and delete your friend’s information. To get started follow the instruction on Vapor documentation and install Vapor to your working machine: https://vapor.github.io/documentation/getting-started/install-swift-3-macos.html

 

You can download the source code for this example from here: https://github.com/JussiSuojanen/friendservice

TIME TO GET OUR HANDS DIRTY

After Vapor is installed open terminal and create a project called FriendService:

creatingproject

Next we can test if the project was created successfully:

 

If you see Server ‘default’ starting at 0.0.0.0:8080 you can open your browser and type localhost:8080 and you should see this page:
 itworks

 

Next hit ctrl + c (kills the running server) and then type:

Vapor will create an Xcode project for you and you can type ‘y’ in terminal to open it. When Xcode opens the first thing you notice is that there is a lot stuff in the ‘Sources’ -folder. At the bottom, you will see the ‘App’ -folder where we will put all our code. You can also run the application from Xcode but make sure you select the app target before hitting the run button.

xcode_run_target

 

First open the main.swift class. Main.swift is the place where you create your Droplet. Droplet is the class that handles all http-requests, routing and setting up the web server. First let’s get rid of all the generated code and try something our own:

Since Vapor has made String to conform to Response protocol we can easily just return a string in our get-request. Now when you build the project and type localhost:8080/hello in your browser. You will see the “Hello Friend!” printed.

MODEL & DATABASE

Next, we will concentrate on our Friends model and the database where it stores all its data. Let’s create a Friend-class under the Models folder. Click on the Models folder to highlight it and then select “File”-> ”New”-> ”File” and select “Swift file”. Give it a name “Friend”. Now there is a bug in the current version of Vapor so you need to close your Xcode and run “vapor xcode” in terminal to open it again so that the project compiles.

 

First we need to make our Friend to conform protocol Model. By doing that we need to add few variables and functions to our class:

Node: implies that your model can be converted to alternative representations such as JSON and values that can be stored to database.
Exists: will tell if our value was fetched from the database or if it was just created using the convenience init method.
Rest of the variables are the information we want to store from our friends.

 

With Model, we also need to conform to JSONRepresentable so we need to implement makeNode-function:

Last thing we need to for the protocol point of view is to conform to Preparation protocol. Create an extension which implements ‘prepare’ & ‘revert’ functions:

Prepare is called when database is used for the first time and it sets up the table for the model.
Revert basically means DROP TABLE -command.

 

After all this is added our Friend class should look something like this:

friendmodel

Next we will setup our model for the Droplet and add the database provider. Open the main.swift folder and add these lines to the Droplet initializer:

We get an error from MySQL-provider since we haven’t yet added it to our project. Lets do that. Open Package.swift and add the provider like this:

You also need to add mysql.json configuration file under the Config-folder you find in your Xcode project. Put this configuration in it:
Make sure the syntax is correct. Otherwise you will get an error like below when preparing your database if something goes wrong.

Close project and run ‘vapor xcode’ to fetch the dependencies. Now when you run the project you’ll notice that it does not work. (huh?)

 

Set up MySQL

First you need to install MySQL to your local machine. With Mac, the easiest way to do so is to use homebrew. Go to http://brew.sh for more information. You can install home-brew using this command:

Next you can install mysql by typing:

Start mysql server:

Connect to mysql server running at localhost:

Create database called Friends:

Verify friends database is created by typing:

Now you can exit and close the connection.

Next lets run ‘vapor run prepare’:

If you get the printed output, it means your friends table is now set up and ready to use. You can verify this from terminal by connecting to mysql server again:

Fluent is a swift ORM Vapor uses to map data between database (MySQL, SQLite, PostQreSQL, Mongo) and objects. The first time you run prepare vapor also creates the ‘fluent’ -table seen in your list of tables.

 

Now we have our Models and database ready. Next thing to do is to have an API we can use to GET information from our database and to POST information to our database.

SETTING UP THE REST-API

Now that we have our database up and running lets get ready to post some content in it. Open main.swift and add the following method:

The code above sets up a route addFriend which needs all parameters firstname, lastname, phonenumber to be present to store the data to database. Here we use the Friend initializer method to create the data and to the store it to database by calling the save-method. We also return the friend to provide some output for the request.

 

Now lets try this out. Select run from Xcode and wait until the service is running. Choose a REST-client to post content to our new service. My favorite tool for the job is Postman:
 postmanpost

 

As you can see we posted some information and the server responded by returning the newly created friend. As we are sending the information as urlencoded you might want to check from the headers tap in Postman that “Content-Type” is set for “application/x-www-form-urlencoded” incase you have any problems.
We also want to list all our friends. That’s easy! Lets create another endpoint called “listFriends”:

Because our Friend class conforms to Model protocol we can call method all() on friends which fetches all the data from our database. Then we use makeNode() to convert it to JSON. Now lets run the project again and open our browser. Type: “localhost:8080/listFriends” to the address line and see all the users which were successfully posted:

 

Now that is pretty much what we need for a simple Rest-API but there is still something we can do to keep the main.swift nice and tidy.

CONTROLLERS

Controllers helps you keep your code in order. We will next create a FriendController which will control our data. Start by adding a new file the same way we have done before. Name the file FriendController.

First we will make our FriendController to conform protocol ResourceRespresetable to make it a restful resource. We need to implement method makeResource() to conform the protocol:

Make resource returns a resource called Friend. Inside the method, we define index & create which we will use to access the resources. Before we do that lets make extension for Resource so we can create a new Friend easily from JSON:

The helper method assumes that we are sending the data in JSON format so next time we send data using Postman the “Content-type” header parameter needs to be set for “application/json” and the data needs to be in JSON-format. In postman, you can send JSON choosing the raw tab under the Body tap and the data format should look like this:
postmanpostjson

 

Now after this is done lets create the index and create methods. Let’s copy-paste the code inside the “listFriends” function to the index-function since it does the exact same thing. Inside the create method we’ll use Request extensions friend()-function to create the new friend and we manage with less lines of code.

At this point we also want to add two new functions to our controller: update & delete. Those will come handy in later blog post when we are creating a client app for our backend.

As you can see update and delete function also takes a friend we are editing as a parameter so the method signature is a bit different from the first two functions we wrote. Second parameter is the Friend we want to fetch from the database. Vapor does this on the background by matching the id in the url on the items in the database. If no matching item is found the route fails. Inside the delete we simply call delete for our unwanted friend and he is out! In update function we have a bit more work. We fetch the new information from our request and update that information for the friend we are editing. After that is done we simply call save and return the edited friend. Now our FriendController should look like this:

 

Now that our FriendController is ready let’s open the main.swift again. The final step is to clear the main.swift file from the add and list functions, create FriendController and add “addFriend”, “listFriends” and “editFriend” as resource with our newly created friendsController as parameter to our droplet:

Now if you build and run it you’ll see that our listFriend and addFriend functions works the same way as previously. But now our main.swift has only few lines of code which in the long run is a great thing. Imagine a few more endpoints in there responding to a few more models. Pretty soon the code gets messy and will be very hard to maintain.

 

We still haven’t test the new update and delete functions so lets do that right away. We know that Arnold had to change his phonenumber after quitting his job as the governor so lets update his number using postman:

 

 

We created a new command called updateFriend and selected the patch http method. We can use the url: “http://0.0.0.0:8080/editFriend/1” and set the id of the friend we are editing as the last part of the url. And after we hit send button we can see server returned the updated data.

 

Ok, next lets delete a friend. We remember that Stone Cold Steve Austin was really getting on everyone’s nerves at the company xmasparty last time so we don’t want anything to do with him. (the ‘beer bashing’ really isn’t working out side the ring..)

 

 

 

We created another command which uses the same url as before but instead of the http patch we use the delete method. After the send button is hit Steve is no longer a member in our trusted list of friends!

 

That is all that I wanted to cover in this post and now you now how to create your own simple restful service with Vapor. In the next post we’ll create a mobile client that uses this new backend we just created.

Leave a Comment

Your email address will not be published. Required fields are marked *