haskell-servant / servant

Servat is a Haskell DSL for describing, serving, querying, mocking, documenting web applications and more!
https://docs.servant.dev/
1.82k stars 412 forks source link

Refactor handleAcceptH #1685

Open ErnestKz opened 1 year ago

ErnestKz commented 1 year ago

Hi, the root of this PR is to change:

    handleAcceptH :: Proxy list -> AcceptHeader -> a -> Maybe (ByteString, ByteString)

to

    handleAcceptH :: Proxy list -> AcceptHeader -> Maybe (ByteString, a -> ByteString)

Here, a is the value returned by the handler, so this is supposed to run after a successful route match. However, the Maybe indicates whether the AcceptHeader is one that we are accepting specified by the Proxy list.

This is a problem because we want to know if the AcceptHeader contains a valid value before we run the handler on it and extract the a. In the original version of the function, we need to run the handler first, and only then we find out if the request contains an appropriate header.

The consequences of this is that we sort force the user to do an additional separate check and then some form of an unsafe coercions/ awkard error throw in order to bypass the Maybe.

Example of awkward error throw: https://github.com/haskell-servant/servant/blob/7ae787371333556a7b84778631ed91d1d73e8370/servant-server/src/Servant/Server/Internal.hs#L326

If it seems like a good idea to introduce this API change. I'm happy to update the rest of the projects in this repo.

Cheers.