Vapor GitHub

You're viewing documentation for an older version. View the latest version

JSON#

JSON is an integral part of Vapor. It powers Vapor’s Config and is easy to use in both requests and responses.

Request#

JSON is automatically available in request.data alongside Form URL Encoded, Form Data, and Query data. This allows you to focus on making a great API, not worrying about what content types data will be sent in.

drop.get("hello") { request in
    guard let name = request.data["name"]?.string else {
        throw Abort(.badRequest)
    }
    return "Hello, \(name)!"
}

This will return a greeting for any HTTP method or content type that the name is sent as, including JSON.

JSON Only#

To specifically target JSON, use the request.json property.

drop.post("json") { request in
    guard let name = request.json?["name"]?.string else {
        throw Abort(.badRequest)
    }

    return "Hello, \(name)!"
}

The above snippet will only work if the request is sent with JSON data.

Response#

To respond with JSON, simply create a JSON object and add values to it.

drop.get("version") { request in
    var json = JSON()
    try json.set("version", 1.0)
    return json
}

Convertible#

Making your classes and structs JSON convertible is a great way to interact with APIs in an organized and DRY way.

Representable#

When something conforms to JSONRepresentable, it can be converted into JSON.

extension User: JSONRepresentable {
    func makeJSON() throws -> JSON {
        var json = JSON()
        try json.set("id", id)
        try json.set("name", name)
        try json.set("age", age)
        return json
    }
}

Now you can simply return user.makeJSON() in your routes.

drop.get("users", User.parameter) { req in
    let user = try req.parameters.next(User.self)
    return try user.makeJSON()
}

You can even go a step further and conform your model to ResponseRepresentable. Since it’s already JSONRepresentable you will get the conformance for free.

extension User: ResponseRepresentable { }

Now you can return the model by itself. It will automatically call .makeJSON().

drop.get("users", User.parameter) { req in
    let user = try req.parameters.next(User.self)
    return try user
}

Initializable#

When something conforms to JSONInitializable, it can be created from JSON.

extension User: JSONInitializable {
    convenience init(json: JSON) throws {
        try self.init(
            name: json.get("name"),
            age: json.get("age")
        )
    }
}

Now you can simply call User(json: ...) to create a user from JSON.

drop.post("users") { req in
    guard let json = req.json else {
        throw Abort(.badRequest)
    }

    let user = try User(json: json)
    try user.save()
    return user
}