-
-
Notifications
You must be signed in to change notification settings - Fork 414
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
Redirect combinator ? #117
Comments
I like this a lot. Here are some thoughts:
|
|
Had a little idea about this. If we don't want to be too opinionated about redirects, we can do: data Redirect (status :: Natural) (c :: [*] -> * -> *) lnk api
deriving (Typeable)
class KnownMethod (c :: [*] -> * -> *) where
methodOf :: Proxy c -> Method
instance KnownMethod Delete where
methodOf _ = methodDelete
instance KnownMethod Get where
methodOf _ = methodGet
instance KnownMethod Patch where
methodOf _ = methodPatch
instance KnownMethod Post where
methodOf _ = methodPost
instance KnownMethod Put where
methodOf _ = methodPut
instance (KnownMethod c, 300 <= st, st <= 307, IsElem lnk api, HasLink lnk)
=> HasServer (Redirect st c lnk api) where |
Nice. For type-safe conformance to the relevant RFCs, I think we'd really want something like
&c. That way, we have a single instance, but all the nuances of the differences between code checked and built-in. Of course, we would probably factor it out as a |
Do you really want to enforce that the method of the endpoint we redirect from should be the same as the link's? That defeats the typical POST new entity -> redirect to its uri. But I'm totally onboard with your suggestion of having types enforce the RFC. |
307 does not allowing changing of method. 303 requires changing to GET. See https://tools.ietf.org/html/rfc7538 |
Any updates on this? I have a little time and could do it. |
Oh, if you want to, please be my guest! I'd definitely be glad to review and then actually use the final |
Ok, @alpmestan and I discussed this a little more. The current proposal doesn't tie the link you actually use with the link in the type at all, which is bad. One option is to get the type for
The alternative is to change the |
Actually, we should be tagging links anyhow. |
I'd be keen to see a PR with the first approach first, and then see if we really need the tagging. I'm not sure of what would be tagged anyway since links just end up being |
How do I redirect to a static file? I'm trying to redirect to a HTML file after successfully doing an insert (CRUD). Tried responseFile but doesn't typecheck because it returns Response. |
You can do it "the good old way" I guess: left $ errXXX { errHeaders = [("Location", "/foo.html")] } where |
@alpmestan thanks for the pointer. CMIIW, servant's using Except instead of Either, right? |
Yeah, in the |
Has there been any more movement on this? I'm surprised that it seems to have died out seeing as (a) redirects are pretty common in http programming and (b) it looks like code for this (or at least a prototype) was already done when this post was made. I don't understand the internals of Servant well enough to implement it myself, but if there's something usable out there (even if not bullet-proof) then I'd be interested in trying it out. Otherwise I guess using ServantErr is the only way to do it? |
ServantErr is the "escape hatch" way to do redirects. The goal of this issue was to discuss some smarter redirection mechanism, one which would be able to check for example that the uri it redirects to belongs to some API type. I wrote the code above for a consulting gig back then and it was working fine. It is however out of data. I agree however that this would be a very useful addition. It would even be about time that we have a proper solution for redirects. @dmjio very recently expressed interest in that too. If we get people to agree on what this redirect combinator should support, what it should look like, I can definitely provide some guidance for anyone interested in implementing it. |
Any news on the progress of this? |
Maybe we could define |
We definitely can define a "shortcut": |
@alpmestan I can't figure out how would nesting
|
Oh, if you have other headers you'd probably instead do: type Get302 (cts :: [*]) (hs :: [*]) a = Verb 'GET 302 cts (Headers (Header "Location" String ': hs) a) where |
That works, thanks! EDIT: server part doesn't compile, let me check. |
There's nothing magic going on above. You just set in stone the things you want (HTTP method, status code, |
Yes - I didn't know GHC doesn't fully resolve type synonyms in error messages, so I was misguided. I'd say having Get/Post 302/301 would be a good step forward towards having redirection and more type safety can be added later on. Would you accept such PR if I give it a try? |
Absolutely (speaking in my name only of course) ! It would be perfect if you could even perhaps mention them in the server part of the tutorial or a small dedicated cookbook recipe? So that people can more easily discover them and how they should be used. |
I'd love to be able to do the following in a type-safe manner using Servant: Consider a simplified "blog" API with endpoints:
The first endpoint asks the API server "what is the This is useful in scenarios where the following conditions apply:
If these requirements are fulfilled, using this redirect schema means a caching middleware can cache responses to Is that what this proposal is about? Specifically, the above requires a combinator which inherits the return type (e.g. |
Hi everyone,
This has been discussed a bit offline but I thought I should open an issue and throw some code in here for discussion and potential inclusion in servant. The deal here is to offer a proper generic combinator for redirection.
One thing however is that we have some decent machinery for generating type safe links, which of course looks like a good basis to build the redirect combinator on.
For a servant-0.4 compatible solution, one could consider such an implementation:
(complete usable code here)
The only thing I'm not happy about is that I hardcode the
303
status code. We could probably take an additional parameter of kindNatural
(type-level natural number) and only have theHasServer
instance when that number is a valid status code used for redirects.Thoughts?
PS: I use the above combinator in a work project already and hence would be keen to eventually include such a combinator in servant itself since I would otherwise have to maintain that combinator independently and adapt it for any change to servant/servant-server.
The text was updated successfully, but these errors were encountered: