If you get this result, congratulations! You have completed the most challenging part of this tutorial.
Every Swift project uses the Swift Package Manager (SPM). Every SPM project requires a Package.json, a main.swift file, etc. The Swift Package Manager will look for the Package.swift file in your Swift project to download the necessary dependencies. SPM is similar to NPM (Node Package Manager). Vapor creates the Swift project, and adds the required dependencies to the Package.swift file.
To create a new project, you must provide Vapor with a project name. First, navigate to a directory where you would want to create the new project, then run the following command:
Vapor will create a project called HelloWorld in your current directory. Navigate to your new project directory, which is the same as the name of the project. In this case, run the following:
You should see a directory similar to the following:
|
|
├── Package.swift
├── App
│ ├── main.swift
│ ├── Controllers
│ ├── Middleware
│ └── Models
├── Resources
| └── Views
├── Config
├── Localization
└── Public
|
Vapor follows and enforces the MVC (Model, View, Controller) pattern. It creates the folders where Models, Views, and Controllers are located in. If you are not familiar with the MVC design pattern,
click here to learn more.
First, Vapor creates the Package.swift file. There is no need to modify it. Then there is the App folder, which contains the Models, Controllers, Middleware, and the main.swift file. The main.swift file is our main app file, and where we initialize our server. Vapor will run this file first.
The Resources folder contains the Views folder, where our HTML files and templates are stored. The Public folder is where our images and styles must go. We won’t be working with the rest of the folders for now.
The Droplet
Vapor automatically creates an example project for us. It will create a Controller, Model, Middleware, and main.swift file. Open the main.swift file (under /Sources/App), and remove all the code inside it.
A Droplet is the heart of a Vapor server. It contains a plethora of functions that will be the backbone of our server. First, import Vapor in our main.swift file:
Then, let’s create a Droplet:
A
Droplet has a lot of customizable properties. It accepts a ton of arguments, all cited in the
Vapor Docs. For this instance we don’t need to customize our
Droplet.
Now let’s try to handle the main
'/' or index request to our web page:
|
|
drop.get("/") { request in
return "Hello World!"
}
|
Finally, you need to call the serve() function. The serve function runs the server.
drop.run()
Now save the main.swift file. Vapor can build and run the server for you. Run the following commands:
Vapor doesn’t have a ‘special’ build or execution. Running the vapor build command simply does a swift build . Entering the vapor run command will run the builds created in the .build/debug/ directory.
This operation might take a while for the first time. After a successful build and execution, you should see something like this:
Vapor initially runs the server on the 8080 port. If you would like to change the port, you must change the configuration by modifying the servers.json file here:
|
|
├── Package.swift
├── App
├── Resources
├── Config
| └── servers.json <--
├── Localization
└── Public
|
Assuming you haven’t changed the port from 8080, navigate to this link to where the server is running:
or
You should see your incredible “Hello World” String!
Note: Every time you make a change, it is necessary first to build, then run the project. If you only run the project, the previous build will be executed.
//-------------------------------------------------------
//-------------------- Method 2 ------------------
Note :- vapor build command not working with Swift 3 : ( Say for Vapor 2 )
Method 2 : -
Try
rm -rf /usr/local/bin/vapor
brew tap vapor/homebrew-tap
than
brew install vapor
or
brew link vapor
if you have installed a new version previously.
Check
To check that your environment is compatible, run the following script:
curl -sL check.vapor.sh | bash
Make new project using SwiftPM
Open your terminal
For our example, we'll be using the Desktop folder.
cd ~/Desktop
mkdir Hello
cd Hello
swift package init --type executable
Your folder should look like this:
├── Package.swift
├── Sources
│ └── main.swift
└── Tests
Edit Package.swift
Open your Package.swift file:
open Package.swift
And add Vapor as a dependency. Here's how your file will look.
Package.swift
import PackageDescription
let package = Package(
name: "Hello",
dependencies: [
.Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1, minor: 1)
])
We try to keep this document up to date, however, you can view latest releases
here
Edit main.swift
A simple hello world:
import Vapor
let drop = Droplet()
drop.get("/hello") { _ in
return "Hello Vapor"
}
drop.run()
Build and Run
The first build command can take a while to fetch dependencies.
swift build
.build/debug/Hello
If different, replace Hello above with the name of your executable.
View
Go to your favorite browser and visit http://localhost:8080/hello
//-------------------------------------------------------
//-------------------------------------------------------
Handling HTTP Requests
Handling an HTTP request is similar to other frameworks such as Express, Flask, etc. We will cover GET in this tutorial.
For instance if you want to output the string "Hello John!" when you open "localhost:8080/name/John". Let’s look at this piece of code:
|
|
drop.get("/name",":name") { request in
if let name = request.parameters["name"]?.string {
return "Hello \(name)!"
}
return "Error retrieving parameters."
}
|
Our Droplet has a GET handler function called get(). The get() function can take multiple arguments. The first argument will be the name of the GET request parameter. The argument that follows will be the key of the that parameter. E.g. :
|
|
drop.get("route", ":key", "route2", ":key2")
|
This way you could access the value of that parameter by supplying the key to a dictionary. The key, or the second argument, must start with a colon, which indicates that the name is the key of the parameter.
The get() function provides us a request object. This object contains everything related to our GET request. To access the parameter which was submitted, use the parameters dictionary of our request object:
|
|
request.parameters["key"]
|
We ensure that the parameter has a value by using the if let statement:
|
|
if let name = request.parameters["name"].string {
// Do something
}
|
The HTTP request needs a response from the server. The response can be returned by just returning the function. In this case, we will return the name string, which was taken from our parameters dictionary.
Try building and running the project. Then go to the following example link to test the GET request:
|
|
http://localhost:8080/name/John
|
You should see the message “Hello John!”
Note that routing is different from other services such as Express. In Vapor, you cannot access the parameters using the URI format:
|
|
http://localhost:8080/name?name=John&age=18
|
A parameter must be supplied using forward slashes:
|
|
http://localhost:8080/name/John/age/18
|
However if you intend to use the URI format, you could do so using the
uri property of the
request object. To learn more, visit
the documentation for the
request object.
Returning a View
Our
Droplet can return a
view to the client. A
view is an
HTML file stored in the
/Resources/Views folder. Download the sample
view.html file linked
here. It is a very simple HTML file that renders a simple web page. After you have downloaded the file, move it to /HelloWorld/Resources/Views:
|
|
├── Package.swift
├── App
├── Resources
| └── Views <--
├── Config
├── Localization
└── Public
|
This directory is where our Droplet will look for views. Now let’s implement the code. Open the main.swift file. Let’s handle the /view route:
|
|
drop.get("/view") { request in
return try drop.view("view.html")
}
|
A Droplet has a view() function that take a string parameter. The parameter is the name of our HTML file.
The view() function throws an exception, therefore it is necessary to mark it with the try keyword. If the view does not exist, the function will throw an exception. You can catch the exception with the catch keyword, but it is not necessary in this case because already we know the file exists.
Let’s build and run:
Now navigate to this link:
|
|
http://localhost:8080/view
|
You should now be able to see the “Hello World” HTML file. To learn more about Templating and Rendering, visit
the documentations.
Deploying to Heroku
Heroku can build and host Swift projects. This is the best, and easiest way to deploy your Vapor project. This tutorial expects you to have some basic knowledge in regards to Heroku. You can use the Heroku toolbelt in order to deploy this project, but in this tutorial, we will push the project to Github and link the two.
First, create a new Github repository. In this case, I will call my repository VaporExample. Navigate to your Vapor project. Initialize the git:
Then, set the remote origin:
|
|
git remote set origin < Your Github Repo Here >
|
Add, commit, and push the repo to Github:
|
|
git add .
git commit -m "Init"
git push -u origin master
|
Alright, now that you have finished pushing the repo to Github, go to your Heroku dashboard. Now create a new app, and name it whatever you want. First, navigate to your settings.
Next, scroll down until you see the “Buildpacks” option.
Then add a Buildpack with the link: https://github.com/kylef/heroku-buildpack-swift. The Buildpack builds your Swift project and tells Heroku what language it is in.
Next, navigate to the Deploy section.
Change the deployment method to GitHub, and add your GitHub Repository name to the app. This connects your Repo to Heroku. Scroll down to Manual Deploy and hit Deploy Branch. Building might take a while.
After it’s built, view your website from the link provided by Heroku!