GithubHelp home page GithubHelp logo

Comments (9)

bergmark avatar bergmark commented on June 16, 2024

rest-example mounts the version directly on the root of the web server, e.g. http://localhost:3000/v1.0/user so I'm not sure what you mean by having to add api to the path?

Specifying the version via HTTP headers sounds like a good idea, we could just allow the version number to be omitted and read the header in that case. Is there a standard header for versioning?

I'm not familiar with this part of the code so perhaps @hesselink can chime in when he gets back to internet land.

from rest.

orclev avatar orclev commented on June 16, 2024

The api thing was just an example, in some projects I've worked on it has been desirable to have the RESTful api mounted under a sub-path, hence /api/v1.0/resful/api. That could probably be worked around using a variety of techniques and is really kind of secondary to the primary issue I was trying to address of providing a way to decouple the API version lookup from apiToApplication and apiToHandler.

I'm not aware of any official standard for specifying versions via header, but one trend (see E.G. github itself https://developer.github.com/v3/) seems to be specifying the version as part of the Accept header. I'm not entirely sure that could sensibly be baked into the standard framework in a fashion that would make everyone happy hence my suggestion to provide a lookup function as an argument. It also occurred to me last night that you'd probably need a way to modify the path to strip out whatever version information your lookup function consumed or else the routing is going to be wonky, not sure exactly what the best way to do that would be.

The short version is, the apiToHandler functions expect the version to be part of the path. I'm using WAI, and the apiToApplication function in rest-wai uses apiToHandler' internally and therefore also expects the version to be part of the path. I'd like to be able to in some fashion specify the version not in the path but instead as part of the Accept header. As an added bonus it would be nice if this same modification also allowed for specifying alternative ways of encoding the version in the path or elsewhere (or possibly even omitting is entirely).

from rest.

orclev avatar orclev commented on June 16, 2024

As an addendum to the previous thought, maybe the solution is to change the signature of the lookup function from RestInput -> Version to RestInput -> (Version, RestInput), the idea being that the lookup function can extract the version info out of the RestInput and provide the stripped version to the rest of the API along with the Version? I feel like most of the guts of apiToHandler and apiToHandler' would remain largely the same and they could be re-written as wrappers around this new function. I.E. if we called it something like apiVersionToHandler you'd have apiVersionToHandler' :: Rest n => Run m n -> Api m -> (RestInput -> (Version, RestInput)) -> n UTF8.ByteString and apiToHandler' would be a wrapper around that that extracts the version from the first path segment. Would probably need to provide an alternative Rest.Driver.Routing.route implementation (currently used internally by apiToHandler') that takes the Version as an argument, but once you have that the rest becomes fairly trivial.

from rest.

L8D avatar L8D commented on June 16, 2024

I would want to add that the versioning in rest is very opinionated and IMO completely useless for most situations. Unless you publish/track each release of your package under a separate name (and keep all the dependency versions compatible across every version) there's no way to actually provide each version of the entire API server implementation. The most you can do is apply versioning to different route configurations, which is understandable but in general pretty useless when you can't distinguish between versions of individual resources.

In general I think the versioning system here should be entirely opt-in, as I'd prefer to handle versioning externally (via headers, proxies, separate domains, etc.).

from rest.

hesselink avatar hesselink commented on June 16, 2024

The current scheme is definitely workable as it's the one we use at Silk :) However, I'm perfectly happy to accept functionality that allows other ways of versioning, or no versioning. If anyone wants to work on this, let me know and I can help you around the code base.

from rest.

L8D avatar L8D commented on June 16, 2024

@hesselink still compiling and setting up GHC and tools atm. In the next week I hope I can get down and hack around with the repo and basically make versioning opt-in. Just from reading the code, I'm guessing it'll come down to changing this function and the underlying definition of Api to look like Single (Some1 (Router m)) | Versioned [(Version, Some1 (Router m))] or something.

from rest.

hesselink avatar hesselink commented on June 16, 2024

Yes, that sounds good. Then in Rest.Driver.Routing.Internal the routeWith function needs to be changed, since it now always expects a version. It takes an Api, so it should probably just pattern match and skip the version check for Single.

from rest.

L8D avatar L8D commented on June 16, 2024

@hesselink So I've gotten the changes implemented locally, ready to commit. The first package that fails to build is rest-gen (because it looks up versions). I'm not sure how I should handle configuration in that case. My options are to make the apiVersion an optional configuration option, that generate will default to "latest" when Api is Versioned or just selecting the single version when Api is Unversioned. I can also just leave the apiVersion option in there, and have generate ignore it whenever the api is unversioned.

from rest.

hesselink avatar hesselink commented on June 16, 2024

@L8D Good to hear! As for rest-gen's command line options, it looks like apiVersion is already optional, and defaults to "latest". I would say that if you have an unversioned api, "latest" should match and anything else should throw an error. The behavior for versioned apis shouldn't change. Does that make sense, or am I misunderstanding the problem?

from rest.

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.