# Using HTTP Message There are two types of HTTP messages, [`HTTPRequest`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPRequest.html) and [`HTTPResponse`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPResponse.html). For the most part they are very similar, but there are a couple of differences. ## Request HTTP requests are sent by clients to a server and they should always receive exactly one HTTP response. HTTP requests contain two unique fields over a standard HTTP message: - [`method`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPRequest.html#/s:4HTTP11HTTPRequestV6methodXev) - [`url`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPRequest.html#/s:4HTTP11HTTPRequestV3urlXev) The method and URL define what content on the server is being requested. ```swift /// GET /hello let httpReq = HTTPRequest(method: .GET, url: "/hello") ``` You can define these when initializing an HTTP request, or set them later if the request is mutable. ```swift var httpReq: HTTPRequest = ... httpReq.method = .POST httpReq.url = URL(...) ``` You can use Foundation's `URLComponents` to create `URL`s from their base components. HTTP request also has a property [`urlString`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPRequest.html#/s:4HTTP11HTTPRequestV9urlStringSSv) that you can use to set a custom URL `String` manually, without going through `URL`. Here is what a serialized HTTP request looks like. This one is querying `/hello`. ```http GET /hello HTTP/1.1 Content-Length: 0 ``` ## Response HTTP responses are generated by servers in response to an HTTP request. HTTP response only has one unique field over general HTTP messages: - [`status`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPResponse.html#/s:4HTTP12HTTPResponseV6statusXev) The HTTP status is used to inform the client of any errors. The status consists of a status code and a reason. The code is always a three digit number and the reason is a short string explaining the code. You can see all of the status codes on [httpstatuses.com](https://httpstatuses.com). ```swift let httpRes = HTTPResponse(status: .ok, body: "hello") ``` All of the commonly used HTTP statuses will have pre-defined values you can use, like `.ok` for `200 OK`. You can also define your own custom status codes. You can define the status when initializing an HTTP response, or set it later if the response is mutable. ```swift var httpRes: HTTPResponse = ... httpRes.status = .notFound ``` Here is an example of a serialized HTTP response. ```http HTTP/1.1 200 OK Content-Length: 5 Content-Type: text/plain hello ``` ## Headers Every HTTP message has a collection of headers. Headers contain metadata about the message and help to explain what is in the message's body. ```http Content-Length: 5 Content-Type: text/plain ``` There must be at least a `"Content-Length"` or `"Transfer-Encoding"` header to define how long the message's body is. There is almost always a `"Content-Type"` header that explains what _type_ of data the body contains. There are many other common headers such as `"Date"` which specifies when the message was created, and more. You can access an HTTP message's headers using the `headers` property. ```swift var message: HTTPMessage ... message.headers.firstValue(for: .contentLength) // 5 ``` If you are interacting with common HTTP headers, you can use the convenience HTTP names instead of a raw `String`. ## Body HTTP messages can have an [`HTTPBody`](https://api.vapor.codes/http/latest/HTTP/Structs/HTTPBody.html) containing arbitrary data. This data can be either static or streaming and can be in whatever format you want. Use the [`contentType`](https://api.vapor.codes/http/latest/HTTP/Protocols/HTTPMessage.html#/s:4HTTP11HTTPMessagePAAE11contentTypeXev) header to describe the type of data. ```swift var message: HTTPMessage = ... message.body = HTTPBody(string: "Hello, world!") message.contentType = .plainText ``` !!! tip Setting the `body` property will automatically update the `"Content-Length"` or `"Transfer-Encoding"` headers if required. ```swift var message: HTTPMessage = ... message.body = HTTPBody(string: """ {"message": "Hello, world!"} """) message.contentType = .json ``` ## Codable Two protocols are defined for making it easy to use `Codable` with HTTP: - [`HTTPMessageEncoder`](https://api.vapor.codes/http/latest/HTTP/Protocols/HTTPMessageEncoder.html) - [`HTTPMessageDecoder`](https://api.vapor.codes/http/latest/HTTP/Protocols/HTTPMessageDecoder.html) These two coders allow you to encode and decode your custom `Codable` types into an HTTP body, setting the appropriate content type headers. By default, HTTP provides conformance for `JSONEncoder` and `JSONDecoder`, but Vapor includes coders for many more types. Here is an example of encoding a `Codable` struct to an HTTP response. ```swift struct Greeting: Codable { var message: String } // Create an instance of Greeting let greeting = Greeting(message: "Hello, world!") // Create a 200 OK response var httpRes = HTTPResponse(status: .ok) // Encode the greeting to the response try JSONEncoder().encode(greeting, to: &httpRes, on: ...) ``` ## API Docs Check out the [API docs](https://api.vapor.codes/http/latest/HTTP/index.html) for more in-depth information about all of the methods.