Getting Started with Server-Side Swift with Vapor 4
Get started quickly with Server-side Swift using Vapor and build your first Vapor web app! By Tim Condon.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Getting Started with Server-Side Swift with Vapor 4
20 mins
Creating Your Own Routes
Now that you’ve made your first app, it’s time to see how easy it is to add new routes with Vapor. If the Vapor app is still running, stop it by pressing Control-C in Terminal. Next enter:
open Package.swift
This opens the project in Xcode as a SwiftPM workspace. It will take a couple of minutes for Xcode to download the dependencies. When it’s finished, open routes.swift in Sources/App. You’ll see the route you visited above. To create another route, add the following after the app.get("hello")
closure:
app.get("hello", "vapor") { req -> String in
return "Hello Vapor!"
}
Here’s what this does:
-
Add a new route to handle a GET request. Each parameter to
app.get
is a path component in the URL. This route is invoked when a user enters http://localhost:8080/hello/vapor as the URL. -
Supply a closure to run when this route is invoked. The closure receives a
Request
object. - Return a string as the result for this route.
In the Xcode toolbar, select the HelloVapor scheme and choose My Mac as the device.
Build and run by clicking the Run button or pressing Command-R. You may be prompted by Xcode to enter your password on this first run, so go ahead and do so. Once you see the “Server starting on http://127.0.0.1:8080” message in the console, visit http://localhost:8080/hello/vapor in your browser.
What if you want to say hello to anyone who visits your app? Adding every name in the world would be quite impractical! There must be a better way. There is, and Vapor makes it easy.
Add a new route that says hello to whomever visits. For example, if your name is Tim, you’ll visit the app using the URL http://localhost:8080/hello/Tim and it says “Hello, Tim!”. Add the following after the code you just entered:
// 1
app.get("hello", ":name") { req -> String in
//2
guard let name = req.parameters.get("name") else {
throw Abort(.internalServerError)
}
// 3
return "Hello, \(name)!"
}
Here’s the play-by-play:
-
Use
:name
to designate a dynamic parameter. -
Extract the user’s name, which is passed in the
Request
object. If Vapor can’t find a parameter calledname
, throw an error. - Use the name to return your greeting.
Build and run. In your browser, visit http://localhost:8080/hello/Tim. Try replacing Tim with some other values.
Accepting Data
Most web apps must accept data. A common example is user login. To do this, a client sends a POST request with a JSON body, which the app must decode and process.
Vapor makes decoding data easy thanks to its strong integration with Swift’s Codable
protocol. You give Vapor a Codable
struct that matches your expected data, and Vapor does the rest. Create a POST request to see how this works.
Set up the request as follows:
- URL: http://localhost:8080/info
- Method: POST
- Add a single parameter called name. Use your name as the value.
-
Select JSON-encoded as the request type. This ensures that the data is sent as JSON and that the
Content-Type
header is set toapplication/json
. If you are using a different client you may need to set this manually.
Your request should look similar to the following:
Go back to Xcode, open routes.swift and add the following to the end of the file to create a struct
called InfoData
to represent this request:
struct InfoData: Content {
let name: String
}
This struct
conforms to Content
which is Vapor’s wrapper around Codable
. Vapor uses Content
to extract the request data, whether it’s the default JSON-encoded or form URL-encoded. InfoData
contains the single parameter name
.
Next, add a new route after the app.get("hello", "vapor")
closure:
// 1
app.post("info") { req -> String in
// 2
let data = try req.content.decode(InfoData.self)
// 3
return "Hello \(data.name)!"
}
Here’s what this does:
-
Adds a new route handler to handle a POST request for the URL http://localhost:8080/info. This route handler returns a
String
. -
Decode the request’s body using
InfoData
. -
Returns the string by pulling the name out of the
data
variable.
Build and run the app. Send the request from RESTed and you’ll see the response come back:
curl http://localhost:8080/info \
-H "Content-Type: application/json" \
-d '{"name":"Tim"}'
curl http://localhost:8080/info \
-H "Content-Type: application/json" \
-d '{"name":"Tim"}'
This may seem like a lot of boilerplate to extract a single parameter from JSON. However, Codable
scales up and allows you to decode complex, nested JSON objects with multiple types in a single line.
Returning JSON
Vapor also makes it easy to return JSON in your route handlers. This is a common need when your app provides an API service. For example, a Vapor app that processes requests from an iOS app needs to send JSON responses. Vapor again uses Content
to encode the response as JSON.
Open routes.swift and add the following struct, called InfoResponse
, to the end of the file:
struct InfoResponse: Content {
let request: InfoData
}
This struct
conforms to Content
and contains a property for the request.
Next, replace the previous app.post("info")
with the following:
// 1
app.post("info") { req -> InfoResponse in
let data = try req.content.decode(InfoData.self)
// 2
return InfoResponse(request: data)
}
Here’s what changed:
-
The route handler now returns the new
InfoResponse
type. -
A new
InfoResponse
is constructed using the decoded request data.
Build and run the app. Send the same request from RESTed. You’ll see a JSON response containing your original request data:
Troubleshooting Vapor
In this and future Vapor apps, you may encounter errors in your projects. There are a number of steps to take to troubleshoot any issues. Here’s some tips:
- Update dependencies
- Clean and rebuild
- Ask the community for help :]