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

