Mickael Belhassen
Mickael Belhassen

Reputation: 3342

Vapor 3: Create Custom Server Response

I want to create a custom server response for my controllers and my errors.

Here is the model:

struct ServerResponse<T: Content>: Content {
    let code: Int
    let message: String
    let data: T?
}

My create request:

func create(_ req: Request) throws -> Future<ServerResponse<User>> {
        try req.content.decode(User.self).flatMap { user in
            user.save(on: req).map { user in
                ServerResponse(code: ?, message: ?, data: user)
            }
        }
    }

In case of success, how can I get the HTTPStatus code to add it to the Response?

And the message if success is OK, if the error is a custom description or the description of the HTTPStatus.

Upvotes: 2

Views: 638

Answers (1)

Caleb Kleveter
Caleb Kleveter

Reputation: 11484

The Content protocol conforms to a ResponseCodable protocol that in turn conforms to a ResponseEncodable protocol. Vapor uses the ResponseEncodable protocol to convert a type to an EventLoopFuture<Response> that it can send to the client.

What you'll want to do is define a custom implementation of the encode(for:) method that ResponseEncodable requires. It will look something like this:

func encode(for request: Request) -> Future<Response> {
    do {
        let response = Response(status: HTTPResponseStatus(statusCode: self.code))
        try response.content.encode(self.data)
        return request.eventLoop.future(response)
    } catch let error {
        return request.eventLoop.future(error: error)
    }
}

I don't really know how you plan on using the message property, so I left that out.

As a side note, you probably only need to conform your custom type to ResponseEncodable instead of Content, but it won't make a big difference.

Upvotes: 2

Related Questions