Pragmatism in the real world

POSTing data using KituraNet

I had a need to send a POST request with a JSON body from Swift and as I had KituraNet and SwiftyJSON already around, it proved to reasonably easy.

To send a POST request using KituraNet, I wrote this code:

let url = "http://httpbin.org/post". 	 // Change to the actual URL
let dataToSend = ["foo": ["bar": "baz"]] // Change to the actual data

// body needs to be of type Data, use SwiftyJSON to convert
let body = try! JSON(dataToSend).rawData()

// HTTP.request() takes a callback that is called when the response is 
// ready. Set up result to extract the data from the callback
var result: [String:Any] = ["result": "No response"];


// create the request
var options: [ClientRequest.Options] = [
    .schema(""),
    .method("POST"),
    .hostname(url),
    .headers(["Content-Type": "application/json"])
]

let request = HTTP.request(options) { response in
    do {
        let str = try response!.readString()!
        if let jsonDictionary = JSON.parse(string: str).dictionaryObject {
            result = jsonDictionary // we got back JSON
        } else {
            result = ["error": "Unknown data format returned"]
        }
    } catch {
        print("Error \(error)") // error handling here
    }
}
request.write(from: body) // add body data to request
request.end() // send request

// result now has a dictionary with either an "error" key or the data returned
// by the server

As you can see, I’ve liberally commented it, so it should be easy to follow. Let’s look at some interesting bits.

SwiftJSON is convenient

SwiftyJSON does all the heavy lifting of converting dictionaries. As KituraNet requires a Data object for the body, we can do this in one line with SwiftyJSON:

let body = try! JSON(dataToSend).rawData()

(admittedly, this assumes a valid dictionary! In a real app, consider better error checking…)

Similarly, if we get a JSON string back from the server, converting it to a dictionary is as easy as:

if let jsonDictionary = JSON.parse(string: str).dictionaryObject {
    result = jsonDictionary // we got back JSON
}

(This time, with some checking!)

Fin

Making a JSON-based POST request is easy enough with KituraNet and SwiftyJSON. Of course, the reason I chose this approach is that they are baked into OpenWhisk which is where this code is running.

I also refactored this code into the methods postTo() and postJsonTo() as you can see in this gist.

2 thoughts on “POSTing data using KituraNet

  1. Hi,
    Great how-to summary which really helped me as I'm struggling to find consistent documentation on the matter.
    What would be the way to handle Body in either application/x-www-form-urlencoded format or form data ?
    I have a hint, i need to call "BodyParser.readBodyData(with:)" but the overall syntax is still pretty obscure…
    Any pointer would be greatly appreciated ! Thanks

Comments are closed.