

# 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
    }