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

formField fails if custom unmarshaller is in scope #541

Open
marekzebrowski opened this Issue Nov 17, 2016 · 5 comments

Comments

Projects
None yet
4 participants
@marekzebrowski

marekzebrowski commented Nov 17, 2016

formField directive fails if there is too generic unmarshaller in scope, that prevents FieldMagnet machinery to work.
It can happen quite a lot - for example when using akka-http-json4s or other generic unmarshaller.

Reproducer https://github.com/marekzebrowski/akka-http-form-field-bug

If it is not solvable, maybe a word of warning in documentation, or a guide how to write own unmarshaller would be helpful

@ktoso

This comment has been minimized.

Show comment
Hide comment
@ktoso

ktoso Nov 17, 2016

Member

Yeah sounds like a docs thing, thanks for reporting.
Up for grabs if someone has the time! :)

Member

ktoso commented Nov 17, 2016

Yeah sounds like a docs thing, thanks for reporting.
Up for grabs if someone has the time! :)

@ktoso ktoso added this to the backlog milestone Nov 17, 2016

@marekzebrowski

This comment has been minimized.

Show comment
Hide comment
@marekzebrowski

marekzebrowski Nov 17, 2016

I wonder if it is a bug. Defined marshaller should work only for application/json content-type. Request in test-case is application/x-www-form-urlencoded. If it is not a bug, it is at least confusing

marekzebrowski commented Nov 17, 2016

I wonder if it is a bug. Defined marshaller should work only for application/json content-type. Request in test-case is application/x-www-form-urlencoded. If it is not a bug, it is at least confusing

@silvaren

This comment has been minimized.

Show comment
Hide comment
@silvaren

silvaren May 15, 2017

Not sure sure if this is the same issue, but it looks very similar. When using circe + akka-http-json support for JSON (which I believe provides generic unmarshallers to the scope) as in:

  private def route(implicit mat: Materializer) = {
    import Directives._
    import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._
    import io.circe.generic.auto._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~
      path("formurlencoded") {
        post {
          formFields('coolKey) { coolKey =>
            complete(s"The cool value is '${coolKey}'")
          }
        }
      }
  }

If I run and test the second route:
curl -d "coolKey=coolValue" -X POST http://localhost:8000/formurlencoded

I get the following error:
The request's Content-Type is not supported. Expected: application/json or multipart/form-data

But if I remove the JSON support it works correctly. Full issue on akka-http-json, but it might be actually an Akka HTTP issue.

silvaren commented May 15, 2017

Not sure sure if this is the same issue, but it looks very similar. When using circe + akka-http-json support for JSON (which I believe provides generic unmarshallers to the scope) as in:

  private def route(implicit mat: Materializer) = {
    import Directives._
    import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._
    import io.circe.generic.auto._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~
      path("formurlencoded") {
        post {
          formFields('coolKey) { coolKey =>
            complete(s"The cool value is '${coolKey}'")
          }
        }
      }
  }

If I run and test the second route:
curl -d "coolKey=coolValue" -X POST http://localhost:8000/formurlencoded

I get the following error:
The request's Content-Type is not supported. Expected: application/json or multipart/form-data

But if I remove the JSON support it works correctly. Full issue on akka-http-json, but it might be actually an Akka HTTP issue.

@jrudolph

This comment has been minimized.

Show comment
Hide comment
@jrudolph

jrudolph Jun 12, 2017

Member

Yes, it's an anti-pattern to bring generic implicits into scope that are able to marshal/unmarshal everything. When you think about it, it is somewhat obvious that this cannot work. So, the recommendation is to never provide something like

def unmarshaller[T]: FromEntityUnmarshaller[T]

where T is basically unconstrained.

Member

jrudolph commented Jun 12, 2017

Yes, it's an anti-pattern to bring generic implicits into scope that are able to marshal/unmarshal everything. When you think about it, it is somewhat obvious that this cannot work. So, the recommendation is to never provide something like

def unmarshaller[T]: FromEntityUnmarshaller[T]

where T is basically unconstrained.

@jrudolph jrudolph added bug and removed bug labels Jun 12, 2017

@jrudolph

This comment has been minimized.

Show comment
Hide comment
@jrudolph

jrudolph Jun 12, 2017

Member

I think we can still improve the situation for formField directives. Right now the FieldMagnet machinery expects implicit FromEntityUnmarshaller[StrictForm] everywhere. Keeping it implicit allows you to override what kind of content the formField directive is able to interpret as a form field and how to parse it. In reality no one will actually override it because the formField directive is thought to be used with multipart/formdata and application/x-www-form-urlencoded payloads. I think we should deprecate the existing implicits and move them into a superclass and provide implicits that don't require that particular implicit (but use a concrete unmarshaller instead).

Member

jrudolph commented Jun 12, 2017

I think we can still improve the situation for formField directives. Right now the FieldMagnet machinery expects implicit FromEntityUnmarshaller[StrictForm] everywhere. Keeping it implicit allows you to override what kind of content the formField directive is able to interpret as a form field and how to parse it. In reality no one will actually override it because the formField directive is thought to be used with multipart/formdata and application/x-www-form-urlencoded payloads. I think we should deprecate the existing implicits and move them into a superclass and provide implicits that don't require that particular implicit (but use a concrete unmarshaller instead).

jrudolph added a commit to jrudolph/akka-http that referenced this issue Jun 12, 2017

!htp akka#541 don't require implicit `FromEntityUnmarshaller[StrictFo…
…rm]` in FieldMagnets

The reasoning is that probably all cases that implicit will be the same. Previous
code allowed that implicit to be customized by users to use `formField` with other
payloads than `multipart/formdata` and `application/x-www-form-urlencoded`. This
isn't really useful and makes `formField` proner to implicit resolution problems.

The old implicit are kept for now to keep binary compatibility but can be
removed later.

jrudolph added a commit to jrudolph/akka-http that referenced this issue Jun 12, 2017

nairbv added a commit to nairbv/akka-http that referenced this issue Jul 26, 2017

jrudolph added a commit to jrudolph/akka-http that referenced this issue Oct 24, 2017

!htp akka#541 don't require implicit `FromEntityUnmarshaller[StrictFo…
…rm]` in FieldMagnets

The reasoning is that probably all cases that implicit will be the same. Previous
code allowed that implicit to be customized by users to use `formField` with other
payloads than `multipart/formdata` and `application/x-www-form-urlencoded`. This
isn't really useful and makes `formField` proner to implicit resolution problems.

The old implicit are kept for now to keep binary compatibility but can be
removed later.

jrudolph added a commit to jrudolph/akka-http that referenced this issue Oct 24, 2017

jrudolph added a commit that referenced this issue Oct 24, 2017

Merge pull request #1188 from jrudolph/jr/w/541-static-formField-unma…
…rshalling

Simplify formField implicits a bit #541
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment