Tutorial: How to set up a Vapor 3 project

By the end of this tutorial you will be able to set up a vapor 3 project and implement a simple route returning a string /number / json ✨

You can find the result of this tutorial on Github here

If you rather like to watch the video on Youtube click here

1. Install Xcode
2. Check Vapor 3 compatibility
3. Install Vapor Toolbox
4. Create your first Vapor project
5. Clean up unnecessary files + code
6. Implement your first route!
7. Configure your own port
8. BONUS
9. Where to go from here

With Xcode you will automagically have Swift 4.1 installed. Go download Xcode from the App Store. And finish the installation by opening Xcode and following the instructions.

When you’re done installing, let us check that your system is ready now for Vapor 3 by executing the following in your terminal:

eval "$(curl -sL check.vapor.sh)"

You should get:

✅  Xcode 9 is compatible with Vapor 2.
✅ Xcode 9 is compatible with Vapor 3.
✅ Swift 4.1 is compatible with Vapor 2.
✅ Swift 4.1 is compatible with Vapor 3.

Before we create our first Vapor project let us install a super convenient command-line interface (cli) that will help us a lot in the future. The one and only Vapor Toolbox.

We will install Vapor Toolbox via Homebrew. If you don’t have it yet I highly recommend to get it. It makes it super easy for you to install dependencies you definitely will need later when creating larger projects with Vapor. To install Homebrew execute the following in your terminal:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Installing vapor toolbox will automagically install all dependencies that are required for vapor to run. How incredible convenient is that ?!

Now add Homebrew Tap and we can finally install Vapor toolbox 😊

brew tap vapor/homebrew-tap
brew update
brew install vapor

Creating a new project is simple as typing:

vapor new projectName

This will create a new project based on vapors api-template. Go inside your projectName/ and create an Xcode project by:

vapor update -y

This may take a while.. but it will fetch all dependencies, generate the Xcode project and open it for you (thanks vapor toolbox 🤜🏻🤛🏻).

You should have a project structure like this now:

projectName/
├── Package.swift
├── Sources/
│ ├── App/
│ │ ├── Controllers/
│ │ │ └── TodoController.swift
│ │ ├── Models/
│ │ │ └── Todo.swift
│ │ ├── app.swift
│ │ ├── boot.swift
│ │ ├── configure.swift
│ │ └── routes.swift
│ └── Run/
│ └── main.swift
├── Tests/
├── Public/
├── Dependencies/
└── Products/

I like to delete (move to trash) everything that is unimportant for now or we are about to implement by our own. That way I want to ensure that we know what we do, need and use. Thus gain a better understanding 😊.

projectName/
├── Package.swift
├── Sources/
│ ├── App/
│ │ ├── Controllers/
│ │ │ └── TodoController.swift // delete
│ │ ├── Models/
│ │ │ └── Todo.swift // delete
│ │ ├── app.swift
│ │ ├── boot.swift
│ │ ├── configure.swift
│ │ └── routes.swift
│ └── Run/
│ └── main.swift
├── Tests/
├── Public/
├── Dependencies/
└── Products/

Note: If you want to learn more about Controllers and Models — I wrote about them, too. You can also follow me to not miss any new tutorials 😊.

Next: delete everything from within routes.swift like so:

import Vaporpublic func routes(_ router: Router) throws {
// nothing left here
}

Within configure.swift delete everything except the router registration lines:

import Vaporpublic func configure(
_ config: inout Config,
_ env: inout Environment,
_ services: inout Services
) throws {
// Register routes to the router
let router = EngineRouter.default()
try routes(router)
services.register(router, as: Router.self)
}

The part we have left here is the one that is fundamental in order to be able to register our routes which we are just about to do. Let’s go!

There are several HTTP Methods from which GET, POST, PUT and PATCH are probably the most known ones. For now we want to GET something - for example a String. Maybe your name? Or GET a number. Maybe your age?

Let’s implement our first GET route by adding to routes.swift:

import Vaporpublic func routes(_ router: Router) throws {  router.get("name") { req in
return "Ethan Hunt"
}

}

By using the function get(“name”) we define that this route is reachable if it is requested via the HTTP method GET at the url /name.

If you now hit cmd + r or the play button on top of Xcode, it will start the application under localhost with the port 8080. You are then able to reach the new route in your browser under: localhost:8080/name.

Note: make sure to select Run as a scheme next to your button before running the app

Note: The port from where you can reach your app is by default set to 8080 😊

You can add more routes and try more out, like returning a number:

import Vaporpublic func routes(_ router: Router) throws {  router.get("name") { req in
return "Ethan Hunt"
}
router.get("age") { req in
return 23
}
}

Don’t forget to run or cmd + r in Xcode after every change in the code in order to recompile it and be able to see the results in your browser 🤓

If you don’t like 8080 it is super easy to change the port of your project. All you need to do is adding the following line to the end of configure.swift:

import Vaporpublic func configure(
_ config: inout Config,
_ env: inout Environment,
_ services: inout Services
) throws {
// Register routes to the router
let router = EngineRouter.default()
try routes(router)
services.register(router, as: Router.self)
let myService = NIOServerConfig.default(port: 8001)
services.register(myService)
}

You are creating a new service NIOServerConfig using it’s static function default. That static function does nothing more but creates an instance of NIOServerConfig but with default values so you only set, what you care about: the port. 🤓

NOTE: For the sake of simplicity I’ll stick to the port 8080 in my tutorials 😊

Now this one might not be straight forward when trying to understand what is actually happening (?!) But I will show you that piece of code and you can start experimenting with it and read more about it in the next tutorial 😊

Within routes.swift add the following code:

import Vaporpublic func routes(_ router: Router) throws {  router.get("name") { req in
return "Ethan Hunt"
}
router.get("age") { req in
return "\(23)"
}
router.get("json") { req in
return Person(name: "Martin J. Lasek", age: 26)
}

}
// Important: your class or struct conforms to Content
struct Person: Content {
var name: String
var age: Int
}

Alrighty! That’s it! You successfully implemented your first Vapor 3 project 🎉!

You can find a list of all tutorials with example projects on Github here:
👉🏻 https://github.com/vaporberlin/vaporschool

I'm an always optimistic, open minded and knowledge seeking fullstack developer passionate about UI/UX and changing things for the better :)