Giter VIP home page Giter VIP logo

Comments (8)

johnnyggalt avatar johnnyggalt commented on July 28, 2024 1

OK, after further testing I had to revisit this and I give up trying to use mustAccept - I just cannot see how to compose it in the manner required. Instead, I wrote my own helper:

let private jsonMimeType = MediaTypeHeaderValue.Parse("application/json")

let acceptsJson: HttpHandler =
    fun (next : HttpFunc) (ctx : HttpContext) ->
        ctx.Request.GetTypedHeaders().Accept
        |> Seq.exists jsonMimeType.IsSubsetOf
        |> function
            | true -> next ctx
            | false -> RequestErrors.notAcceptable (text $"Client does not accept MIME type: {jsonMimeType}") next ctx

This can be plumbed through with the fish operator in an intuitive manner:

GET >=> acceptsJson >=> authenticated >=> routef "/something/%O" getSomethingHandler

Here's hoping I don't find any more gotchas 🙈

from giraffe.

johnnyggalt avatar johnnyggalt commented on July 28, 2024

OK, I worked it out - sorry. Something like this:

let handler: HttpHandler  =
    choose [
        mustAccept [ "application/json" ] >=>
            choose [
                subRoute "/v1" v1Handler
            ]

        RequestErrors.notAcceptable (text "Not accepted")
    ]

from giraffe.

johnnyggalt avatar johnnyggalt commented on July 28, 2024

Actually, wait, no. That means that if the resource is not found I'll get a 406 rather than 404 😢 I remain confused and would really appreciate a pointer in the right direction 🙏

from giraffe.

johnnyggalt avatar johnnyggalt commented on July 28, 2024

I landed on this helper function, which I'm not overly happy about, but don't know if there's a better way to achieve my goals:

let mustAcceptJson (inner): HttpHandler =
    let mimeType = "application/json"
    choose [
        mustAccept [ mimeType ] >=> inner
        RequestErrors.notAcceptable (text $"Client does not accept MIME type: {mimeType}")
    ]

I use it like this:

route "/user_info" >=> mustAcceptJson (authenticated >=> userInfoHandler)

Any suggestions for refinement are welcome.

from giraffe.

64J0 avatar 64J0 commented on July 28, 2024

Hi @johnnyggalt, thanks for opening this issue and for posting the advances you're making, it could definitely be useful for other people too!

I'll try to take a look at this problem during this week.

from giraffe.

64J0 avatar 64J0 commented on July 28, 2024

Actually, wait, no. That means that if the resource is not found I'll get a 406 rather than 404 😢 I remain confused and would really appreciate a pointer in the right direction 🙏

So you want:

  1. A middleware that checks whether the request has the necessary mime type header (for example, application/json), and returns the 406 status code if it does not have (short-circuit to the error);
  2. And keep returning the 404 status code if the route does not exist.

Is that it?

from giraffe.

64J0 avatar 64J0 commented on July 28, 2024

OK, after further testing I had to revisit this and I give up trying to use mustAccept - I just cannot see how to compose it in the manner required. Instead, I wrote my own helper:

let private jsonMimeType = MediaTypeHeaderValue.Parse("application/json")

let acceptsJson: HttpHandler =
    fun (next : HttpFunc) (ctx : HttpContext) ->
        ctx.Request.GetTypedHeaders().Accept
        |> Seq.exists jsonMimeType.IsSubsetOf
        |> function
            | true -> next ctx
            | false -> RequestErrors.notAcceptable (text $"Client does not accept MIME type: {jsonMimeType}") next ctx

This can be plumbed through with the fish operator in an intuitive manner:

GET >=> acceptsJson >=> authenticated >=> routef "/something/%O" getSomethingHandler

Here's hoping I don't find any more gotchas 🙈

I think this is the best approach. For instance, you're doing something similar to what mustAccept does: https://github.com/giraffe-fsharp/Giraffe/blob/master/src/Giraffe/Core.fs#L222-L240.

from giraffe.

johnnyggalt avatar johnnyggalt commented on July 28, 2024

you're doing something similar to what mustAccept does

Right, but that's why I thought I should be able to use mustAccept in the first place, but it does not compose in the manner required. I'm curious whether people are using mustAccept because to me it seems useless because you end up stuck if you want a "standard" experience of 406 for incorrect Accept headers whilst retaining other things like 404 for undefined routes.

PS. I'm perfectly happy with the implementation of acceptsJson I came up with, so this is now more a curiosity about mustAccept than anything else.

from giraffe.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.