Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple content-types per service #575

Closed
vkostyukov opened this issue Mar 21, 2016 · 4 comments · Fixed by #794
Closed

Support multiple content-types per service #575

vkostyukov opened this issue Mar 21, 2016 · 4 comments · Fixed by #794
Assignees
Milestone

Comments

@vkostyukov
Copy link
Collaborator

The easies solution would be to introduce a wrapper around Endpoint that captures two types - its underlying type and a content type. Something like:

val service = (
  getUsers.respond[Application.Json]
  getFoos.respond[Application.Xml]
).toService

I think we have to keep in mind that at some point we will introduce content-type member for decoder and I guess there should be a symmetric variant of respond for that.

val user = body.as[User].accept[Application.Json]
@vkostyukov
Copy link
Collaborator Author

My most recent idea is to try to attach content-type to Endpoint:

trait Endpoint[A] {
  type ContentType
}

But keep Output content-type-free. We can default to JSON for body and endpoints created with Mapper, but use text/plain for everything else (headers, params). This would allow us to reuse this type when resolving decoders. So basically having a single content-type on endpoint means we can use it in both places: when resolving encoders and decoders and this is really nice.

When composing two endpoints, the content-type will turn into a coproduct so we can expect one-by-one mapping.

Given that JSON is going to be a default, we can keep the API unchanged but mark Endpoint trait deprecated in favour explicit Endpoint.Json or even Endpoint.Aux.

@vkostyukov
Copy link
Collaborator Author

vkostyukov commented Apr 14, 2016

I wonder how people feel about the following syntax:

val getUsers = post[Application.Json]("users" :: body[Application.Json].as[User]) {
  Ok("users")
}

Making content-type a type member on Endpoint allows us to drop it at any point w/o any trouble (eg: we can compose :: endpoint w/o worrying of content-type of left and right sides). Although, we need to make sure it's specified at the end of the day (before applying :+:).

Not sure this is super readable though, but this is the only thing I can think of today.

@crispywalrus
Copy link
Contributor

If I assume that post[Application.Json] could be :+:ed with post[Text.XML] and it could be attached to other extractors (such as body from your original sketch) then I like that. 👍

@vkostyukov vkostyukov modified the milestones: Finch 1.0, Finch 0.11-M1 Jul 14, 2016
@vkostyukov vkostyukov modified the milestones: Finch 0.16, Finch 1.0 Jun 12, 2017
@vkostyukov
Copy link
Collaborator Author

I'm throwing this into the 0.16 milestone. The idea is to ship something similar to #583 (as an experimental API) and see if gets some adoption.

@vkostyukov vkostyukov self-assigned this Jun 12, 2017
@vkostyukov vkostyukov changed the title Support multiple content-types per coproduct endpoint Support multiple content-types per service Jun 13, 2017
@sergeykolbasov sergeykolbasov mentioned this issue Oct 8, 2017
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants