A Vapor practical guide, by a lazy student.
It's been a while since last time I wrote here, but here I am again.
So, as a Swift guy, I asked myself:
Does Swift has something like that for APIs and/or Servers?
Fortunately, there is! It's Vapor!
I started my research with the Ray Wenderlich's book Server Side Swift with Vapor. I had been around on Swift universe for some time, even had published some apps at AppStore. Although, I’m not well known with every framework and library as I would like. So, why not give it a try to Vapor and see if would be fun as Node.js was when integrated with React.js.
So, as a way of registering all I'm learning. I decided to do this guide. Maybe some people will find it useful, others will not, but it's okay as it fit for the purpose of teaching someone about Vapor and keep me stimulate to learn. I hope you like it.
Come, let’s get our hands dirty!
I will start from very beginning. From installing the Vapor to some HTTP methods, if you have already installed Vapor and are used to the initial project template, you can skip to the next section.
Open your terminal (I’m using iTerm, you can use your native terminal, or anything you like it).
Type this command on your terminal (or copy and paste):
brew install vapor/tap/vapor
This command will install Vapor on your computer. After that, you can create a folder that you may use to store your projects. Call it whatever you want. Then open this folder on your terminal. Bellow there are commands that make these steps but through terminal.
The former is creating at your root a folder named 'vapor'. The latter is changing your directory to the folder named 'vapor'. Repeating myself, because I really like details: you can change the name and place to whatever and wherever you want.
Bellow there is a command that will create a new Vapor project.
vapor new VaporFirstStep -n
Have you questioned yourself: what is that -n? This is a flag that will say no to every question that may appear when creating a Vapor project. If everything run well, this screen will appear to you:
Alright, let's get inside of this project.
cd VaporFirstStep (I believe that you already know what this
cd command does)
I will not explain about the folder structure and about Swift Package Manager (SPM). But, if you want to learn more about it, take a look in this link for the Folder Structure and this link for the SPM, is the official Vapor documentation.
vapor xcode to open your Vapor project on Xcode. Then, wait Xcode finish the packages fetching.
Let's take a first look on Xcode.
Open the file indicated by the red arrow. Here are some default GET methods that you can make a request in your browser.
Build and run your project (Assure that your device selected is My Mac. On my Xcode print it was marked as iPhone, but should be My Mac instead of). Wait, wait, waaaait, and nothing happened.
Your server is running already, but there is no interface to be showed. Open a browser (I will be using Google Chrome just for the guide, I'm a Safari guy).
http://localhost/8080 (8080 is the port that Vapor uses). You should see this:
Indeed, it works!
If you navigate to
http://localhost:8080/hello Vapor shall say hello to you.
At this moment, you used those two GET methods that were already on your project. If it's the first time that you are seeing HTTP methods, but you have already known a CRUD. Here is a table that links HTTP methods and to CRUD, it's from Wikipedia, and fits well for a very, very, very quickly explanation.
GET methods are interesting to read data from our API (this term fits well to what we are doing, so I will call this way), with that you can ask some data and get as response a JSON data. We will not receive a JSON response right now, only in the POST Methods, but I assure that you can do this later. I shall use a default answer, or part default and part custom answer in the GET methods.
It's time my friend, time has come to build our first custom GET method (by now, I shall use Github Gists to paste my code here). Let's start easy, we will add another route to the path, that will return other phrase.
Add this function bellow the two previously default methods. Then, build and run. Now, to access this method you need to type this URL:
There is our GET method's response. So every string that you add as parameter to your method, is another route that you create for your API.
You may be thinking:
How do I create dynamic routes?
Let's check it out.
Again, add this function at bellow our last method. This function should receive a name as a parameter and print the name passed through the URL path and print it.
This is our output:
What about numbers then? Of course you can pass numbers too!
Type or copy and paste this bellow our last function:
If you are well known with Swift statements, you should know the
guard let statement. For those who don't, the guard let statement assures that a number will be received, if don't, will abort the request returning an error. If you still want more info about
guard let, check this link.
This output is what happen if you pass an integer as parameter. Everything is functioning as expected.
And this one is what will happen if you pass a string as parameter. An error answer as response in JSON format.
Before we start looking POST methods, Vapor has another ways to implement HTTP methods. I will not explore them, but if you are curious I will show the alternative way of GET method now and at the final of the POST method section the alternative way of POST method.
This is the output.
The output is not different than before.
GET methods are fun, but we should interact with our API sending data to it. And why not receiving data from it too? So, funnier than receive data, is sending data. Funnier than that, is receiving data from the API, when you have sent some data. Funnier than that, is sending data… Ok, that is enough.
So remember, GET is for read and POST is for write. We shall now start to send data to our API. Later, we will see how to send data and receive a response in JSON.
But first: how do I send data to my API? Currently, I can open the localhost address through my browser, see that there are a path, that answers my request. I change my question to: how do I send data to my API through the browser? If you search on internet, you may find a way or another of how to do that. I even quickly googled and this result appeared this: link. At this link, you will find a lot of different answers. However, I will not use the browser to make POST requests to our API. I will use a program that makes POST request to our API.
For this section, to test the POST methods return, I will use Insomnia. You can use Postman or whatever you want. JSON will be used for communication, then you need to create a structure that will be used to receive data and send data.
So, make sure to add these structs in your code.
Indeed, they are simple. However, they will help turning that JSON data into something that Swift can understand. Besides that, you can use these structs inside your API as any normal struct you are used to.
This is the function that will be added below the last functions. This is our first POST method! Hurray! 🎉
Here is the input and output at Insomnia.
Notice that we sent though the same path a hello to our API. Maybe you are asking:
Shouldn’t this return ‘Hello, world’? Like was in our first GET method.
Nope, the requests are different. When you do a GET request, our API will respond in a manner, when you do a POST request, our API will respond in another manner.
That is not all, you can receive a JSON data as an answer too. This is interesting if you want to handle a data that comes as an answer in an application that consumes your API.
Just add this function bellow the last one.
The input and output will be:
To end this chapter of our journey, here you can see a different way of doing POST methods. Everything will works as before.
Now you have the power to build a very simple API that receives GET and POST requests, in other words, a very simple API that you can interact with it. That is really cool!
I don't know how many parts will be, but I hope to teach something about everything. And if you have suggestions or doubts, you can send me a message. I gonna be glad to answer.
I hope that you've liked so far. Thank you for reading and see ya!