Kitura 2.0 – Taking advantage of Codable Routes

Share this post:

A Swift evolution

Swift on the server remains a fresh frontier for the primarily-mobile programming language. Though the language itself is evolving at a rapid pace, the server side segment of the language is beginning to see an increase in adoption.

Keeping in line with Swift’s evolution, IBM’s Server Side Swift framework, Kitura, has taken the next step in its own evolution. Kitura 2.0 comes with a number of improvements over its predecessor – a handy CLI, commercial support, KituraKit – but none more impactful than Codable routes.

What does Codable mean?

It’s not as fishy as it might sound to a Swift novice – it dramatically simplifies how you implement routes in Kitura. Codable is a new protocol that was introduced in Swift 4. Its purpose is to allow you to create any model object that is both encodable and decodable into and out of JSON, or any external representation.

JSON parsing has always been difficult, if not at least roundabout in Swift – the Codable protocol aims to make it a much easier operation to complete, avoiding the JSONSerialization class altogether.

Can you show me how?

Let’s assume you have a struct called Acronym, defined like so:

struct Acronym: Codable {
var id: String?
var short: String
var long: String

For Codable routing to work, the object in question must conform to Codable, which is, in reality, a typealias of the combined protocols Encodable and Decodable. Conforming to these protocols means that the Swift runtime will be able to serialize the object into JSON, using the property names as tags, and back from JSON into a model object representation.

Let’s look at an example of a basic GET route for your Acronym object from the previous version of Kitura:

router.get("/acronyms", handler: getAcronyms)

func getAcronyms(request: RouterRequest, response: RouterResponse, next: @escaping () -> Void) throws {
Acronym.Persistence.getAll(from: database) { acronyms, error in
defer {
guard let acronyms = acronyms else {
response.send(JSON: ["error" : error?.localizedDescription])
response.send(JSON: ["acronyms" : acronyms.json])

Let’s examine what this route is doing. If a client makes a GET request to this API at /acronyms, it calls the getAcronyms function, that you have designated as its handler. You then use a function on the Acronym type to get all acronyms you have saved to your database, aptly named database. This closure returns an optional collection of acronyms, and an optional error. You parse through them, send either the error or the acronym array back in the response, then call next(), and you’re all set.

This is a fair approach to handling a GET request for a particular type, and if you’ve ever used Express.js, then this will seem quite familiar to you.

Now, let’s take a look at how that same API call can be done with Codable routing:

router.get("/acronyms", handler: getAcronyms)

func getAcronyms(completion: @escaping ([Acronym]?, RequestError?) -> Void) {
Acronym.Persistence.getAll(from: database) { acronyms, error in
return completion(acronyms, error as? RequestError)

Quite literally, Codable routing allows you to handle this GET request in half the amount code. You designate the route handler function just like before, and then call your function to get your acronyms from your database. The only difference is that Kitura will handle the response serialization for you now.

Cool, right?

What’s happening under the hood?

Let’s take a look at the pre-requisites for a JSON route to be considered Codable:

  • The object being transferred must conform to the Codable protocol.
  • The request must include the header Content-Type: application/json.
  • A body-parser cannot be used.

This means you have to consider how your requests are being made from a Web front end. Previous tutorials using a basic HTML form allowed you to just specify the REST verb and the API path, but including the content type is paramount now. For example, let’s say you also declared a route to add a new Acronym via a POST. Here’s how you would form your XMLHTTPRequest in your Web front end:

function submitForm() {
var short = document.getElementById("shortField").value;
var long = document.getElementById("longField").value;
var xhr = new XMLHttpRequest();"POST", "/acronyms");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
xhr.send(JSON.stringify({ "short": short, "long": long }));

Once you make this call, this function gets called in Kitura:

public func post<I: Codable, O: Codable>(_ route: String, handler: @escaping CodableClosure<I, O>) {
postSafely(route, handler: handler)

Passing in your generic input JSON and output type expectation, this leads you to the culmination of our bullet list above, called at the very beginning of postSafely:

guard self.isContentTypeJson(request) else {
guard !request.hasBodyParserBeenUsed else {
Log.error("No data in request. Codable routes do not allow the use of a BodyParser.")

We won’t dive into the specifics of isContentTypeJson and hasBodyParserBeenUsed, but you can take it on fair authority that they do what they say they do!

Neat – how can I get started?

We’ve built a tutorial entirely predicated on the use of Codable routes – FoodTracker. You can clone the repository and follow along with the entire tutorial to get your own Swift API up and running in no time with Codable routing.

More How-tos stories
April 30, 2019

Introducing IBM Analytics Engine v1.2 and Announcing the Deprecation of IBM Analytics Engine v1.0

We are excited to inform you about the new version of IBM Analytics Engine v1.2 that will be available starting May 15, 2019. Along with this release, Analytics Engine v1.0 will be retired.

Continue reading

April 23, 2019

Announcing the Deprecation of the Watson Machine Learning JSON Token Authentication Service

We’d like to inform you about the deprecation of the Watson Machine Learning JSON Token Authentication service. This method of authentication will be retired on May 30, 2019.

Continue reading

April 9, 2019

IBM Cloud Continuous Delivery is Now Better with Unlimited Insights

Starting this month, we are bundling IBM Continuous Delivery and IBM DevOps Insights to make the build, test, deploy, and learn experience on IBM Cloud even better.

Continue reading