Getting Started With Server-Side Swift and Amazon Smoke
Do you find yourself wanting to leverage your Swift skills on the backend and don’t know where to start? In this tutorial, you’ll build a REST API using Server-Side Swift and Amazon Smoke. By Jonathan S Wong.
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 and Amazon Smoke
20 mins
- Getting Started
- Smoke and RESTful API Routing
- Creating a GET Topic Operation
- Creating the Response
- Adding Topics
- Adding Route Handlers
- Defining Errors
- Specifying Operations
- Conforming to Smoke Protocols
- Configuring the Application Server
- Running Your Server
- Creating a POST Topic Operation
- Adding a Response Object
- Combining the Request and Response Objects
- Adding a Route
- Validating Your Data
- Troubleshooting
- Where to Go From Here?
Do you find yourself wanting to leverage your Swift skills on the backend and don’t know where to start? If you need a lightweight way to create a REST API backed by one of the most influential and innovative companies in the world, give Amazon Smoke a try. It’s built on top of SwiftNIO, like Vapor and Kitura.
By leveraging Swift and the power of protocols, you’ll see how easy it is to get up and running with Smoke.
In this tutorial, you’ll use Server-Side Swift and Amazon Smoke to build the Level Up REST API, which helps you track topics to learn to progress your career on this never-ending journey as a software developer. You will learn how to configure a Smoke server to accept GET and POST requests and how to respond to these requests.
Getting Started
Start by downloading the project materials using the Download Materials button at the top or bottom of this tutorial. Then open Package.swift in the starter folder.
Xcode will pull down the required dependencies for this tutorial: the Smoke framework and its dependencies.
The starter project includes a Topic
model that you’ll use to keep track of what you’re studying, along with the amount of time you plan to study it. A TopicStore
is used to keep track of the various topics. Finally, An ApplicationContext
is used in each of the input requests to the server and is also included in the starter project. This is where the TopicStore gets initialized.
Before you start working on your server code, it’s time for you to learn some of the basics of Smoke and REST.
Smoke and RESTful API Routing
REST is an acronym for Representational State Transfer. In RESTful apps, each unique URL represents a resource. In this tutorial, you’ll have one such resource — Topic, which you’ll use with RESTful verbs like GET to fetch topics and POST to add new topics.
In Smoke, you provide various operation functions to handle the RESTful verbs. Smoke decodes the request into the operation’s input along with the ApplicationContext
and encodes the response in the operation’s output.
You can think of operations as functions you use to set up the requests and responses in a REST API.
The ApplicationContext
is created when the server starts up and is passed to each operation handler.
Creating a GET Topic Operation
Create a new Swift file called TopicsGetRequest.swift in the LevelUp group. Replace its content with the following:
import SmokeHTTP1
import SmokeOperations
import SmokeOperationsHTTP1
import SmokeOperationsHTTP1Server
// 1
func topicsGetOperation(
input: TopicsGetRequest,
context: ApplicationContext
) throws -> TopicsGetResponse {
// 2
TopicsGetResponse(topics: context.topicStore.topics)
}
// 3
public struct TopicsGetRequest: Codable, Validatable, Equatable {
// 4
public func validate() throws {}
}
Don’t worry about the resulting compilation error, you’ll deal with it momentarily.
In the code you just added, you:
- Add an operation to handle the GET request for a topic. The input is of type
TopicsGetRequest
, andApplicationContext
is also passed to the operation. The return type isTopicsGetResponse
, but you haven’t created this yet. This means you can’t build right now — but you’ll fix that in a moment. - Return the response for the operation, which is of type
TopicsGetResponse
. In the response, you useApplicationContext
to fetch thetopics
from thetopicStore
. You’ll create both of these in a moment. - Define
TopicsGetRequest
. This type conforms toCodable
,Validatable
andEquatable
. You’re required to use theValidatable
protocol for input requests and output response types. - Add an empty
validate()
, to satisfy theValidatable
protocol conformance.
Now that you have the request, it’s time to create the response.
Creating the Response
Create a new Swift file called TopicsGetResponse.swift with the following code:
import SmokeHTTP1
import SmokeOperations
import SmokeOperationsHTTP1
import SmokeOperationsHTTP1Server
// 1
public struct TopicsGetResponse: Codable, Validatable, Equatable {
// 2
public var topics: [Topic]
public init(topics: [Topic]) {
self.topics = topics
}
// 3
public func validate() throws {}
}
This should look similar to TopicsGetRequest
above. You:
- Define
TopicsGetResponse
. LikeTopicsGetRequest
, this type conforms toCodable
,Validatable
andEquatable
. - Define an array of
Topic
s, which the response will return. - Add an empty
validate()
to satisfy theValidatable
protocol requirement.
Adding Topics
There’s one last step you need to do before you can build successfully. What good is a TopicStore
if you can’t add any Topic
s to it? You’ll fix that next.
In ApplicationContext.swift, add this property to TopicStore
:
var topics: [Topic] = []
Then, add the following line to addTopic(_:)
:
topics.append(topic)
These two lines of code create an array to hold all the interesting topics you intend to learn about. They then configure addTopic
to add topics to add to this array.
Time to build the work you’ve done so far. Make sure to select My Mac in the device pop-up and press Command-B. A successful build tells you that everything’s set up correctly so far, but you aren’t ready to run the server yet.
Adding Route Handlers
Now that you’ve created your first operation, it’s time to define which operation gets run for the incoming requests.
Start by creating a new Swift file called ModelOperations.swift. Add the following code to it:
import SmokeOperations
import SmokeOperationsHTTP1
// 1
public enum ModelOperations: String, Hashable, OperationIdentity {
// 2
case topicGet
// 3
public var operationPath: String {
switch self {
case .topicGet:
return "/topics"
}
}
}
extension ModelOperations: CustomStringConvertible {
// 4
public var description: String { rawValue }
}
- To add the operation for a route, you need to define a type that conforms to
OperationIdentity
. - You create a
case
for each of your routes. Since you only have one route so far, you create a single route to GET topics. - The
OperationIdentity
protocol requires anoperationPath
property. This is where you define the GET topics route as aString
. - Lastly, you implement the description property to satisfy the
CustomStringConvertible
protocol. This is in a separate extension to keep the code neat.