Server-side Swift update project to Vapor 2.0

Hello friends! In this blog post I’ll tell you all you need to do to update your server-side-swift Vapor project from version 1.0 to 2.0. At the start of 2017 I did a small server-side-swift project named FriendService using Vapor 1.0. I wanted to develop it a bit further and add some error handling, so that it would be closer to a proper service. A lot have happened in the last 8-9 months with Vapor, so the first thing to do is to update it from 1.0 to 2.0. I couldn’t find good instruction on how to do that, so I decided to write one myself. You can find all the codes on GitHub. There is a tag Vapor1.0 for the older version of the project as well as Vapor2.0 for the new version.

droplet creation after udating project to vapor 2.0

Update Vapor project to 2.0 version

 

Update project for Vapor 2.0

Now, there are a few steps you need to do to update the project. After Vapor released the 1.0, Apple has released Swift 3.1 version, which comes with an update to package manager. Vapor also made some changes to Droplet creation and configuration, and Model and Controller (ResourceRepresentable) interfaces. They also introduced some new configuration files, and made changes to Crypto files. All in all, not that much have changed, but enough that I had some trouble when moving to 2.0.

So these are the steps you need to make:

  1. Update Vapor using homebrew
  2. Update Xcode to get the latest version from swift
  3. Update package.swift
  4. Make changes to Model
  5. Make changes to Controller (ResourceRepresentable)
  6. Update Droplet creation and configuration
  7. Update configuration files

Update tools and Xcode

First thing you need to do is to update the tools. Make sure you have the latest version of Vapor.

After you have run the command you should see this output on the terminal:

Incase something went wrong, make sure you have the latest version of homebrew installed. If it is still not working, check the error printed on the terminal carefully. It should point you to the right direction.

Updating Xcode is easy, just open the App store and select update. Incase you have the latest version you can ignore this step.

Update packaging file

Next, move on to package.swift. The old version looked like this:

All you need to do is to change the dependencies. The minor version is no longer needed, since small changes are non-breaking, and always work on top of the major version. Keep the paths unchanged, remove the minor version and set major versions to 2.

After the modification the file should look like this:

Next thing to do is to update the project to see if all works as it should:

After answering ‘yes’ for regenerating the Xcode dependencies and for opening the Xcode, it is time to check what has changed. When you look at the project folder you should notice that there is a file called Package.pins.

Swift package manager pins project dependencies

Package.pins is a new file that comes with swift 3.1 package manager update. It is a file that locks the correct versions of the packages that your project is using. It is generated from the package.swift file, and makes sure the project uses correct versions. This way you don’t need worry about it, when you deploy your project to Heroku for example. Incase you are familiar with cocoa pods, you can think the pins file as the Podfile.lock.
 
If you try to build the project now, you’ll notice it won’t compile. It complains about a VaporMySQL module which is not found. There is also some other things that you need to take care of before the project will compile.

Update Model for Vapor 2.0

If you are familiar with the friend service, you might remember that there is a model called Friend. It’s job is to store all information from a friend. As with previous version, the model protocol is called Model, but the interface has changed a bit. Id and exists variables have been replaced with a storage variable. This is constructed with Storages default constructor:
 
The Model protocols function parameters have also changed. There is no longer Context or Node which you might remember from the 1.0 version. Context is removed completely and Node is replaced by Row. While Node was a wrapper for database transferring data back and forth, it is no longer needed. It is replaced with a simpler concept Row, which represents a row or an entity in a database. Because of the changes mentioned, the function signatures have changed.
At first let’s checkout the default constructor:

In the 1.0 version you can see the Node and Context parameters as well as the id variable. When you compare it to the 2.0 version:

You notice that Row now replaces Node as mentioned, and the Context is missing completely. Now check the makeNode function from the 1.0:

When you compare to the 2.0 version:

You don’t need to give Context as a parameter anymore, and the name has changed to makeRow (quite convenient!). Also the return value is now Row instead of Node.

 
Another thing is that the database prepare, and revert functions were previously defined inside the friend class. Now they are defined inside an extension which conforms to protocol Preparation. In the 1.0 version prepare and revert was declared like this:

As with 2.0 you notice the extension which conforms to Preparation protocol:

And holds the functions inside the extension.

There is also some helper protocols that Vapor introduced after the 1.0 release. Not sure if it was before the 2.0 release, but for me these were new things: JSONConvertible and Updateable. JSONConvertible is a helper protocol for JSON handling:

It helps you to create an object from JSON and also convert an object back to JSON.

Updateable handles data updates inside the database:

The last protocol the Model needs to conform is ResponseRepresentable. By adding this extension to Friend class, Friend type can be returned directly in the route closures:

Also notice that you need change the “import Fluent” statement to: “import FluentProvider” at the beginning of the file. That is actually all that you have to do. You can check the complete code for Friend class here: Friend.swift

Updating FriendController

What is new with controller? A little less compared to the Model protocol. Again the Node protocol is removed, so makeNode and node as a parameter is out. Other than that the “VaporMySQL” import is replaced with “MySQLProvider”. Other changes are so small that it is easiest just to look at the file and compare it to old one. Here is the updated file after all the changes have been done:

To summarise, the code looks cleaner and has a few less lines compared to previous version. Part of the reason is the JSONConvertable and Updataeble protocols that are now in use in the controller code.

Whats new in Droplet in Vapor 2.0?

In 1.0 version you could add all preparations and providers in the droplets constructor. Now you need a configuration variable. You add all models and providers to configuration, and Droplet takes it as parameter in its constructor. Other than that all has stayed pretty much the same. You create a controller and add it as resource with correct routes to the droplet. Then you call run for the droplet to start the service. Now the run command can throw an error so you need to add “try” in front of the call. You can check the differences from the old file:

compared to the updated file:

Now can I run the project?

If you hit run from the Xcode, you’ll notice that the project is still not working. First make sure that the mysql.server is running on your machine, and that target is App > MyMac. I am sad to tell you that even after these changes the app won’t work. There is still one configuration file needed. As you can see from the error provided, fluent.json is missing:

So you also need to provide a configuration file for fluent. All you need to do is to create a new file under the config folder named fluent.json and add these lines to it:

The file simple provides all the information fluent needs to be able to present the data in the wanted format.

The last thing that you need to do, (and I promise you, this is the last thing) is to change the crypto.json file to look like this:

Now if you clean and run the project the server is starting in localhost and you can POST & GET to interact with it.

Conclusions

Moving from 1.0 to 2.0 with Vapor was pretty straight forward. It would have helped to find an article to describe all the changes, but it wasn’t all that hard to do it by trial an error. I created a new project using 2.0 version and compared my old project to that to see all the differences. I hope I was able to help you to migrate to Vapor 2.0. If there is something that is still not clear, don’t hesitate to ask!
 
Incase you want to know more about friend service, you can check my old post here: FriendService. I also created a mobile app using MVVM-pattern which uses the backend. If you want to learn more about it, you can check from here: FriendApp.
Thank you for reading and have a great day my friend!