It is believed that Swift - especially due to the development in the open source - is already applicable beyond the scope of software for Apple platforms. Our colleagues from Rambler, including the developer Samvel Mejlumyan, even try this language as a server solution. At the CocoaHeads community meeting, Samvel listed the finished products for building a Swift server, compared them to each other and showed a short demo.
- My name is Samvel, I am an iOS developer at Rambler. Before joining mobile development, I was engaged for a long time in server products, various integration systems, targeting systems that provide APIs for third-party resources, websites of our webmasters and partners. At the moment I am engaged in the project "Poster Restaurants".
At the end of a small bonus, how to organize a good API, a couple of best practices and my opinion on the prospects of S3. ')
I hope many of those present here share my sympathy for Swift. This is a terrific tool that gives us tremendous opportunities, and now also the opportunity to implement the server part. And we can implement end to end on Swift, that's awesome.
Let's go back a couple of years ago. On June 2, 2014, I was sitting in the room of the Saratov dormitory honey. It is not so important for those present here, if you do not take into account the fact that on this day I, like many of you, waited for an important event. It's about WWDC, at which Apple introduced Swift. And a year later, on December 3, 2015, Apple started Swift, releasing it under the Apache license for Linux and OS X. This was a great event, it launched a huge wave of various projects and additionally motivated those developers who wanted actively distribute Swift outside of development for Apple devices. Awesome time.
Let's dig the root cause. This is the April statistics of the share of Internet traffic. A huge number, which suggests that most of the applications that we use and, especially, which I want to believe, develop, have a connection to the network and various services.
Thus, the business logic of our applications is somehow divided into parts. This causes certain dependencies. Part of the logic, whether it is application authorization or booking a table, is on the back. This creates problems, dependencies. We all don't like addictions. Ultimately, this limits us.
This is not to take into account the fact that the majority of backendors are quite jealous of our wishes, comments, requests to change something in the API, add, correct. You can explore a standalone tool, become a backend yourself, but this solves the problem only for us. What about the team? Suppose we have an iOS team and need to implement a server utility for our needs. For example, in the "Rambler" there is a dashramb written in Ruby, and support is now quite problematic.
Implementation end to end on Swift solves this and a number of other problems.
The concept of the backend framework is somewhat different from what we are used to. By definition, from a wiki, a framework is a software system, a framework that allows you to organize our system. This is a kind of platform. This is not a library, this is not an additional language, not a new language for us. There is nothing supernatural about using the framework for any normal developer.
At the moment there are four actively developing tools. The total number of stars in the repositories of these tools reaches 31 thousand. And the oldest tool is Perfect, it is just over one and a half years old.
For comparison, the "rails" for seven years, only 35 thousand. Community development is a huge step.
I propose a comparison of components and proceed to the demo.
Community When launching a project it is very important. Perfect and Vapor stand out here, they have a huge community, a huge number of contributors, followers on Twitter, the most active channels in Slack, where you can quickly get an answer to any of your questions.
As for Kitura and Zewo - get ready to dig a lot of code, you will not get quick answers, but they have other chips. In the future, Zewo’s last commit was made on January 13, 2017, although the framework seems to be evolving.
Languages. With the exception of Vapor, all tools have one, two or more dependencies in C. Perfect is an HTTP server, Kitura has template engines implemented in C. Different cryptographic libraries. In part, it justifies itself in speed.
If you look at the available online benchmarks, then Vapor loses to all frameworks and Node.JS. This is a benchmark for memory usage and a benchmark for processing and issuing JSON.
I have information that in the new version, which is in beta, this problem is solved and everything is optimized there, so we are waiting for a stable version.
As for working with the database, it is equally well implemented in almost all tools except Zewo, there is a little problematic. Perfect and Vapor provide a huge number of providers for organizing access to different relational databases.
What is my choice? Despite the fact that Vapor is inferior to all tools in speed, I choose this framework. It is laconic, its syntax cannot but please the Swift-developer, plus the ideological commitment is exclusively Swift style, plus Vapor has a huge community, quite active, they are fictitious, constantly make new changes. So this is my choice.
What do you need to do to install and deploy the system? The first is to put the toolbox. Tulbox Vapor - just a wrapper for the terminal, which allows in a convenient form to call those or other commands. Just ask for a brew, he will do everything for you.
Create a new project. You can specify as a template parameter any template found on GitHub.
The third step is to go to the project folder and bring it down. The first build causes network dependency download. To avoid fakapov with a network, I made a pre-incremental build in advance.
Start your server and everything is ready.
In addition, I recommend calling the xcode command, which will create your target, this is your usual development environment, nothing supernatural.
What are the parts of the compiled server project?
First of all, it is Package.swift. There is nothing supernatural in this file, many are familiar with it, this is a package of dependencies that pulls us from the server. And MySQL provider.
I would like to specifically mention the file main.swift, which initializes the droplet object. This is the core layer, giving us access to all the other Vapor chips.
Here also the routing for the index query is thrown, which shows us view welcome and runs. I propose to start the server and see how great it all is.
The server is running, it is located at localhost on port 8080.
Who wants to see firsthand the process of installing Vapor, compiling, pulling in dependencies - I will show you how to call the commands in the terminal and enjoy this process during the break.
Server configs are in the configs folder. You can configure the necessary parameters and change the port of your system. The default port is 8080.
Let's return to our project. Such a server is useless unless you want to make some kind of online business card to show your friends. And of course, if you want to do something more, you need to connect the database.
How does Vapor work with different relational databases? We have a driver that provides interaction with the database. The provider connects to it. Under the hood, the driver interacts with the Fluent engine, developed by guys from Vapor. We work directly with MySQL-provider. Think of this provider as persistent store in core data, then everything will become clear.
I chose MySQL as the base. To install it, you need to call two commands - brew install mysql and start the MySQL server.
Let's create a DB. I have a blank, the base dump is in a project that will be available after the presentation. This is the only table that contains four fields with events about CocoaHeads events that we want to issue to our API.
To create and manage the database after installing MySQL, you can use various utilities, it is not necessary to call these commands from the terminal. One such tool is Sequel Pro. This is a utility whose interface is no different from the core data management interface in Xcode. The same structure: create objects, create fields for them, specify content, data.
I propose to show how to connect the provider. You need to import VaporMySQL and add the provider to the drop-object. It is executed by one command - addProvider (VaporMySQL.Provider.self). In principle, everything is already ready to work with the database, this is enough.
After starting the project, you will see that the server is running. No prepared objects.
When you start and install a new object, you have models out of the box. They should be compared with the tables that you create in your databases. In this case, I have an event model, which is fully consistent with the table in the MySQL database. To connect it to my provider, I call the preparation module command, the model is added to my provider.
In principle, everything. I can send this object by different routing and get them on the server.
Add a group of requests for the version path of API 1. The events event will handle the event controller. We start the project, we see that DPS prepared, the database is fully connected.
Let's check the query that is located at events. The query group and the entity itself. We receive our event, and the API works literally in three lines, not counting the connection of the base. I propose to show all objects, not only those on which the registration is open. The process of working with some components of Vapor is no different from working with Realm, core data, and you only need 20-30 minutes to study some components to start it. And out of the box everything will be ready. Check the request. We get all the events that are in the database.
Let's return to the report. I'll put in a couple of principles about organizing a good API. A poorly structured API can cause you a lot of pain and trouble later on.
First of all - versioning. I showed that my version of the API is clearly indicated.
I avoid point notations and group queries in this way. Of course, you can create different requests for different versions, but this will eventually confuse you as a backend developer.
Throw out mistakes. I have a bad experience with the API, which always throws out the 200th code, but in the request body there is an incomprehensible message: error E, error C, error xs. The only developer who invented it all knew what it was.
Well, if there is any documentation, but there it was not. A good tone is the explicit indication of the response status and a unified body, which can be parsed the same for all requests.
Addiction is pain. Remember this. Your backend and your client should be independent of each other. A change in business logic on one component should not entail a change in another. This is a good way to diversify project development.
What do I think about Server Side Swift? It seems to me that Swift in this direction has a great future. First, Apple invests in this huge amount of money. By creating a Swift API group, Apple has shown its interest in this. Plus, this group involves not only third-party developers of these frameworks, but also Apple employees. Other companies are investing in this. IBM developed Kitura, which also invests a lot of money and promises to transfer all its servers to Swift. Of course, we do not know when this will happen. But let's hope for the best. The huge community, which was formed in a year and a half, is actively developing. People actively interact with each other, while being competitors.
Most importantly: Swift Server Side is not a compromise. I mean, this is not about some kind of hipster solution. Swift is not inferior in speed to leading compiled languages. This is a separate topic of the report, but you can find benchmarks, where the speed of Swift is approximately comparable. On these benchmarks, Swift outperforms Node.JS.
That's all. Use Swift Server Side for home projects and be happy. Thank.