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

Index

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


1. Install Xcode

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.


2. Check Vapor 3 compatibility

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.

3. Install the Vapor Toolbox

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

4. Create your first Vapor project

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 🤜🏻🤛🏻).


5. Clean up unnecessary files + code

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 Vapor
public func routes(_ router: Router) throws {
// nothing left here
}

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

import Vapor
public 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!


6. Implement your first route!

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 Vapor
public 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 Vapor
public 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 🤓


7. Configure your own port

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 Vapor
public 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 😊

8. BONUS: Return JSON

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 Vapor
public 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 🎉!


9. Where to go from here

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


I am really happy you read my article! If you have any suggestions or improvements of any kind let me know! I’d love to hear from you! 😊