--- currentMenu: http-request --- > Module: `import HTTP` # Request The most common part of the `HTTP` library we'll be interacting with is the `Request` type. Here's a look at some of the most commonly used attributes in this type. ```swift public var method: Method public var uri: URI public var parameters: Node public var headers: [HeaderKey: String] public var body: Body public var data: Content ``` ### Method The HTTP `Method` associated with the `Request`, ie: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`. ### URI The associated `URI` of the request. We will use this to access attributes about the `uri` the request was sent to. For example, given the following uri: `http://vapor.codes/example?query=hi#fragments-too` ```swift let scheme = request.uri.scheme // http let host = request.uri.host // vapor.codes let path = request.uri.path // /example let query = request.uri.query // query=hi let fragment = request.uri.fragment // fragments-too ``` ### Route Parameters The url parameters associated with the request. For example, if we have a path registered as `hello/:name/age/:age`, we would be able to access those in our request, like so: ```swift let name = request.parameters["name"] // String? let age = request.parameters["age"]?.int // Int? ``` Or, to automatically throw on `nil` or invalid variable, you can also `extract` ```swift let name = try request.parameters.extract("name") as String let age = try request.parameters.extract("age") as Int ``` These extract functions can cast to any `NodeInitializable` type, including your own custom types. Make sure to check out [Node](https://github.com/vapor/node) for more info. > Note: Vapor also provides type safe routing in the routing section of our docs. ### Headers These are the headers associated with the request. If you are preparing an outgoing request, this can be used to add your own keys. ```swift let contentType = request.headers["Content-Type"] ``` Or for outgoing requests: ```swift let request = Request ... request.headers["Content-Type"] = "application/json" request.headers["Authorization"] = ... my auth token ``` #### Extending Headers We generally seek to improve code bases by removing stringly typed code where possible. We can add variables to the headers using generic extensions. ```swift extension KeyAccessible where Key == HeaderKey, Value == String { var customKey: String? { get { return self["Custom-Key"] } set { self["Custom-Key"] = newValue } } } ``` With this pattern implemented, our string `"Custom-Key"` is contained in one section of our code. We can now access like this: ```swift let customKey = request.headers.customKey // or let request = ... request.headers.customKey = "my custom value" ``` ### Body This is the body associated with the request and represents the general data payload. You can view more about body in the associated [docs](./body.md) For incoming requests, we'll often pull out the associated bytes like so: ```swift let rawBytes = request.body.bytes ``` ## Content Generally when we're sending or receiving requests, we're using them as a way to transport content. For this, Vapor provides a convenient `data` variable associated with the request that prioritizes content in a consistent way. For example, say I receive a request to `http://vapor.codes?hello=world`. ```swift let world = request.data["hello"]?.string ``` This same code will work if I receive a JSON request, for example: ```json { "hello": "world" } ``` Will still be accessible through data. ```swift let world = request.data["hello"]?.string ``` > Note: Force unwrap should never be used. This also applies to multi-part requests and can even be extended to new types such as XML or YAML through middleware. If you'd prefer to access given types more explicitly, that's totally fine. The `data` variable is purely opt-in convenience for those who want it. ## JSON To access JSON directly on a given request, use the following: ```swift let json = request.json["hello"] ``` ## Query Parameters The same applies to query convenience: ```swift let query = request.query?["hello"] // String? let name = request.query?["name"]?.string // String? let age = request.query?["age"]?.int // Int? let rating = request.query?["rating"]?.double // Double? ``` ## Key Paths Key paths work on most Vapor types that can have nested key value objects. Here's a couple examples of how to access given the following json: ```json { "metadata": "some metadata", "artists" : { "href": "http://someurl.com", "items": [ { "name": "Van Gogh", }, { "name": "Mozart" } ] } } ``` We could access the data in the following ways: ### Metadata Access top level values ```swift let type = request.data["metadata"].string // "some metadata" ``` ### Items Access nested values ```swift let items = request.data["artists", "items"] // [["name": "Van Gogh"], ["name": "Mozart"]] ``` ### Mixing Arrays and Objects Get first artists ```swift let first = request.data["artists", "items", 0] // ["name": "Van Gogh"] ``` ### Array Item Get key from array item ```swift let firstName = request.data["artists", "items", 0, "name"] // "Van Gogh" ``` ### Array Comprehension We can also smartly map an array of keys, for example, to just get the names of all of the artists, we could use the following ```swift let names = request.data["artists", "items", "name"] // ["Van Gogh", "Mozart"] ```