Redis and Vapor With Server-Side Swift: Getting Started
Learn how to use the in-memory data store, Redis, and Vapor to cache objects by saving them in JSON, then configuring them to expire after a set time. By Walter Tyree.
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
Redis and Vapor With Server-Side Swift: Getting Started
20 mins
Redis is the most popular key-value data store for high-performance storage and caching. In this tutorial, you’ll learn how to add Redis to a Vapor project to cache API responses. You’ll also explore some of the other features of Redis using the command-line interface (CLI).
To do this, you’ll add caching to a new web app: Your Daily Dog. This app fetches a new image of a cute dog to display on your site. At the beginning of the tutorial, the app retrieves a new dog record from the API for each page reload. By the end of the tutorial, you’ll ensure that everyone who visits during a set period of time will see the same dog picture.
When speed is critical, a Redis cache can help your app be “Best in Show”. Other tricks Redis can do include:
- Storing session states
- Replacing parts of a database
- Maintaining a sorted list
- Storing and brokering messages
This app uses data from The Dog API, which is a public API for viewing cute dog pictures. Hopefully you aren’t allergic to dogs. :]
This tutorial uses Leaf to render web pages. For more information about Leaf, read Templating Vapor Applications With Leaf.
This tutorial uses Leaf to render web pages. For more information about Leaf, read Templating Vapor Applications With Leaf.
Getting Started
Download the starter project by clicking the Download Materials button at the top or bottom of this tutorial, then navigate to the starter folder. The sample app has been tested on macOS and Ubuntu.
Open the Vapor app in Xcode by double-clicking Package.swift. If you’re not using Xcode, open Terminal and navigate into the starter folder. Then type swift build
to pull all the dependencies and build the app. The project contains three folders:
- Resources: Contains the web template used to render your app’s web page.
- Tests: Contains a test for one of your routes.
- Sources: Contains the source files for your Vapor app.
Open Sources/App/routes.swift. You’ll see two routes. app.get("hello")
is a placeholder route to make sure your app is running and listening. A test in the Testing folder will exercise this route. app.get
is the more exciting route. Here’s how it looks:
app.get { req -> EventLoopFuture<View> in
//1
let apiURL = URI("https://api.thedogapi.com/v1/images/search")
//2
return req.client.get(apiURL).flatMap { res -> EventLoopFuture<View> in
//3
guard let freshDog =
try? res.content.decode(Array<Dog>.self).first else {
return req.view.render("index")
}
//4
return req.view.render("index", freshDog)
}
}
This route does a few things. It:
- Defines
apiURL
to point to the endpoint, where it will fetch a dog record. - Issues a
get
request to the URL. - Attempts to decode the response from the DogAPI as
Dog
. - Passes the decoded
Dog
to Leaf for rendering.
Next, go to Dog.swift, where the coding magic happens. By conforming to the Content protocol, Vapor automatically manages all the encoding and decoding for you. This lets you easily use the structs in your app.
Running the App
Enter swift run
in the command line. On Linux, you may need to type swift run --enable-test-discovery
, depending on what flavor and version combination you have.
For Xcode, you need to set the working directory so Vapor can find the Leaf template. To do that, open the scheme editor by left-clicking dailydog in the top bar to open the pop-up, then selecting Edit Scheme.
Under Options, select Working Directory, then click the folder icon and select the root of your project.
Once you’ve selected your project, click Choose.
Now, build and run.
Regardless of how you got your project running, use a web browser to navigate to localhost:8080 to enjoy a picture of a cute dog, like this one:
{"error":true,"reason":"expected array at key: breeds"}
. If that happens, keep reloading the page until a dog appears.
Every time you reload the page, you’ll see another dog. Your next task will be to add Redis and use it to cache a dog so everyone can enjoy the same picture for a while.
Adding Redis
Vapor has built-in support for Redis, which uses RediStack behind the scenes. See the official documentation for more details.
Your first step is to open Package.swift. Then, add a dependency for the Vapor/Redis library in the dependencies
section:
.package(url: "https://github.com/vapor/redis.git", from: "4.0.0"),
Now, link the package to an import product in the app’s dependencies
section:
.product(name: "Redis", package: "redis"),
Now that you’ve imported the Redis library, you need to tell it where to find the Redis server. If you’re using Docker, the Redis server will be at localhost
. When you use Redis in production, it will be at a different IP address.
To achieve maximum speed, Redis assumes that it’s in a trusted environment. That means it doesn’t encrypt things, as a slower database server might. You can learn more about securing Redis at the official documentation.
Open configure.swift and add Redis to the import
statements at the top:
import Redis
Finally, initialize Redis on startup by replacing TODO: Configure Redis
line with:
app.redis.configuration = try RedisConfiguration(hostname: "localhost")
Starting Docker
This tutorial assumes you have the Docker daemon installed and running. See the note at the beginning of this tutorial if you need help. Start a Docker Redis container by entering the following into the command line:
docker run --name dog-cache -p 6379:6379 -d redis
This creates a container named dog-cache running on the standard Redis port of 6379
. The -d
flag detaches the process from the current shell.
Return to routes.swift and add Redis to the import
statements at the top:
import Redis
Next, find the app.get("hello")
route and replace this line:
return req.eventLoop.makeSucceededFuture("Hello, world!")
with the following:
return req.redis.ping()
Build and run. This time, browse to localhost:8080/hello.
You’ll see the word PONG in an otherwise blank webpage. The /hello route executed the Redis .ping()
command. The Redis server responded with PONG. This is the standard connectivity test, which you can learn more about in the Redis documentation.
So far, you’ve gotten Redis running and connected it to your Vapor app. However, when you refresh the web page at localhost:8080, the dogs keep changing. For your next step, you’ll update the app so that when you fetch the first dog, Redis will cache it and return the same dog on future requests.