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 }