TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
RESTFul API & Kohana
  • I like to create my own RESTFul API with Kohana, do you know of any module I can use for this?

    Ideally I like to API to be:

    http://api.domain.com/<version>/<controler&gt;(/<resource>(/<id>)).<json|xml>(?<parameters>)
    

    Thanks,

    Sebicas

  • You can use Route for that.

  • And classes/controller/rest.php that comes with Kohana

  • I've been working on the same, check this thread with valuable comments from Sam de F.

    FuelPHP has a decent rest controller that handles both authorization and format conversion in a nice way. I've ported most of it to Ko 3.1 (not http digest authorization part), trying to separate the authorization and format conversion stuff into separate classes. I will try to GIT it up asap, so that you can check it out if you're interested.

  • Quick note, stuff like .json in the URL is not RESTful.

  • @Zeelot3k: Perhaps not "best practice", but nevertheless "common practice", isn't it..?

  • Quick note, stuff like .json in the URL is not RESTful.

    I'm not so sure about that. AFAIK, The REST architecture doesn't describe how urls should look. It only says that urls should describe resources.

    And appending the format is the only way to link to a resource in a specific format. You can't make a link send an accept header.

  • I would expect you should set request headers to ask for a type of resource rather than adding ".json". You can use the "accept: application/json" to request a JSON resource. Of course offering ".json" makes it easier for beginners to use your service.

  • As far as I know there is no standard practices... @cambiata have you uploaded your code to Github? I would love to start working in a module like that... do you want to do it??

  • @sebicas: Now I've Gist'ed them:

    Maybe you can find them useful!

  • I've been to a good talk about Restful webservices (http://www.slideshare.net/Wombert/designing-http-interfaces-and-restful-web-services-phpbnl11-20110128) by David Zülke, creator of the Agavi framework.

    The talk comes down to:

    • create meaningful urls that don't have to change in the future.
    • use the http verbs
    • instead of only returning the requested data return metadata as well, like next and previous links, to make the client as thin as possible.
  • @xwero same talk I was going to link to :) excellent stuff!

    @cambiata the 'common practice' you are referring to isn't RESTful at all. The issue is that so many people want to call their APIs RESTful when they don't have any idea what that even means. Most of the APIs work just fine, just don't call something RESTful unless it really is.

  • @Zeelot3k: That's why I like to call my APIs RESTlike. I can get away with anything this way... ;-)

  • @cstuder hahaha, awesome idea! Completely acceptable, in my opinion :)

  • @ikke: it would seem to me like example.com/photos.json example.com/photos.xml example.com/photos.html example.com/photos.monkeys are all different URLs pointing to the same resource.

  • The do point at the same resource, but they would give you different output back, obviously.

  • Check out slides 52 and 53 of the talk, the output format is set in the http headers.

  • I know how it "really" works.

  • @xwero: Great post! I will follow cstuder's naming praxis in the future! :-)

  • @zombor the remark wasn't meant for you personally. I don't doubt that you know how it should work.

    People shouldn't name things by how they look. I know developers who name iframe location changes ajax because the content has changed using javascript.
    I guess buzzwords are too big of a cashcow not to abuse them.

  • How to send a post Data using Rest API

  • Give me an example how to post,get from our controller via rest API

  • Hi All, I came across this discussion while searching around for tips and guidance on writing my own API. A good one-hour read!

    Now if anyone is up for it, I'd appreciate it if someone help me answer this...

    Said slide suggests URLs should be resource-aware, e.g. products/id/photos/ etc. Notice by default Kohana's route (I'm using 3.2) suggests beginners to do <controller>/<action>/<id> in their URLs, this way is not REST-recommended, is it? I am well aware of the fact that it is designed to be flexible and what not but unfortunately things have grown quite a bit since we last modified the bootstrap file for our application.

    So, just a philosophical question here: What should we do at this point? ... I guess I'm more concerned about the fact that our application is already deployed in production and we actually update the application bits by bits. Seems like if we are to start steering towards this URLs as described in the slides, we'll first need to maintain a few sets of routing rules combined with some url rewrites to keep all links working, basically keeping a few versions of URLs until the old ones are completely phased out (after several update iterations to the application)??

    p.s. Sorry if I should not have digged old discussions up ^^;;

  • Usually, you create a bunch of routes. For APIs, on Day 1, I usually version it right away

    http://domain.com/api/v1/...
    http://domain.com/api/v2/...
    

    so that people can have a chance to migrate. I usually EOL (end-of-life) version 1 for a year (bug fixes only) and then add new features to the version 2 to encourage people to switch

    Thanks, Chris

  • The version in the url is a terrible idea. Don't do it, ever.

  • What he said… no more being afraid of headers!

  • Maybe explain why it's a "terrible idea", instead of just stating it?

    Github enterprise API is currently:

    http://yourdomain.com/api/v3/

    Twitter:

    https://api.twitter.com/1.1/

    Tumblr:

    http://api.tumblr.com/v2/

    So why are they wrong and doing it this way instead of versioning media types via Accept/Content-Type? This is worth a discussion.

  • Versioning looks fine to me.

  • Because it's not restful. You have two urls pointing at the same resource:

    /v1/account /v2/account

    The only difference here would be the output formatting. You should use the accept header to specify the version of the resource you are requesting. There's some more detail here: https://news.ycombinator.com/item?id=1523664 and google will help with more details.

    Just because github and twitter does it, doesn't make it right.

  • @zombor Interesting, would it be possible, that you post an example of request and response headers with versioning? I mean, how you deal with this? There seems to be multiple ways to do this.

  • We use the following request header in our app: Accept: application/json; version=2

    We currently only support one version at a time in our API, so we don't have to route to different versions. Eventually, we do plan on supporting this, but we haven't had time to implement it yet. We currently just check the version and return a 406 if it's not the currently supported version number.

  • @zombor

    It's also not RESTful to just return generic json or xml that require out-of-band information rather than specific media types and not RESTful unless hypertext-driven and self-describing according to the man himself but nobody does that because it's a PITA. Do you expect your API clients to do the 'right' thing in the full 'chatty' way by starting from only a single root entry point '/api/' and follow all hypertext links from there without any knowledge or documentation of other URIs and their methods, and only knowledge of how to process the given media types?

    So Github is trying to move away from versioned media types like 'application/vnd.github.beta+json' to a version-less, hypermedia-driven API, but obviously there's a cost and a trade-off and the benefits of this level of RESTfulness are a matter of debate for many - just look at the comments on Roy Fielding's post and his inability to clearly articulate those benefits with working examples. It's obviously more helpful to discuss these trade-offs and compromises.

  • Because it's not restful. You have two urls pointing at the same resource:

    That's just academic nonsense. As far as 99.9999% people using an api are concerned you pick one and throw everything in the void. If you're using v2, v1 just doesn't exist.

    Personally I think the whole accept header variant is for people fixing their broken api moreso then people making a new one.

    Having the version directly in the url is much nicer since it makes it so much easier to pass around and process. It's also a lot more robust, no "oh you forgot the header do-thingie you must have meant v1 then, here you go" etc and far easier to program since a lot of languages have annoying header manipulation.

  • If you're using v2, v1 just doesn't exist.

    Yah, so specify the header and forget about it. Even if you don't care about the "two resources" thing, it's just clutter in the url anyway.

    oh you forgot the header do-thingie you must have meant v1 then, here you go

    No, in our api you must specify an accept header. If you don't, you get a 406 like I said.

    far easier to program since a lot of languages have annoying header manipulation.

    Red herring.

  • It's also not RESTful to just return generic json or xml that require out-of-band information

    So because we don't do one thing right, we should forgo the whole thing and be idiotic with the whole thing? Get real. Versioning with the accept header is not hard (yes, even for your consumers it's not hard), and it's The Right Thing To Do™

    For the record, we have planned on doing this method, but again, we haven't had a chance to implement this yet. Again, Not doing something completely correct doesn't mean you should do everything wrong.

  • @zombor

    Well, if you are free to pick and choose which parts you decide to do 'right', maybe users here do too? Or are you not capable of imagining that others may have gone through a similar process of deciding what was manageable and practical for them within the given resources and constraints, and compromising accordingly? I suppose it's just easier to dismiss all that stuff with a curt remark that does nothing but make users feel like idiots, rather than actually try to explain yourself. Is it any wonder why this place is a graveyard?

    And for the record, version-less and hypermedia-driven is clearly The Right Thing To Do™ - but a PITA.

  • My point was versioning with a header is stupidly easy to do, and there's no reason to choose any other way.

    rather than actually try to explain yourself.

    I actually did explain myself in my second post: You have two uris pointing to the same resource.

  • Stupidly easy does not make it right, and there's every reason not to do it that way or in the url either - version-less and hypermedia-driven is clearly The Right Thing To Do™ and there's no reason to choose any other way. See, I can do that too.

  • See, when you put the "version" into the accept header, it's not really a "version". It's the client's contract with the server that "I accept this kind of content". HTTP content types are for specifying different kinds of content. Different formats (versions, if you will) of content goes in the accept header.

  • HTTP content types are for specifying different kinds of content. Different formats (versions, if you will) of content goes in the accept header.

    So what exactly happens when v2 starts having more dangly bits then v1? By your model you should be going back to the obsolete v1 and adding in this new nonsense (like if anyone using v1 cared and had the time, they would want to keep using v1 instead of v2).

    What about the implementation for this header approach? As I see it you basically have to create an entire specialized routing system specifically for managing the api, because the alternative is to have controller spaghetti code where a controller is constantly bloated with v1 code, v2 code, v3 code, etc.

  • By your model you should be going back to the obsolete v1 and adding in this new nonsense (like if anyone using v1 cared and had the time, they would want to keep using v1 instead of v2).

    That's a product question, not a technical one. We only bump our version if we change an existing format, we don't bump for adding things.

    Basically you have to create an entire specialized routing system specifically for managing the api

    This isn't that hard.

    Or you could go the facebook route, and say "fuck you clients, we are changing the api, I hope your apps are updated!"

    :)

  • For the definitive list of different versioning strategies for REST APIs, including many examples of usage by major sites read How are REST APIs versioned?

    And from there, for a discussion of the full-on, properly version-less and hypermedia-driven approach (real HATEOAS and "agent-driven content negotiation") read this - notable both for its correctness and the difficulty of implementing it efficiently. Most would baulk at this purest of implementations, I'm guessing.

    (There's also this even fuller HATEOAS example with the full workflow on InfoQ: How to GET a Cup of Coffee).

  • @zombor Thank you for clarification. Is there way (in Kohana) directly route Accept -header versions to different Controllers/Actions?

    Another dilemma, any ideas for good directory structure?

  • you can route based on anything in the request object by using route filters: http://kohanaframework.org/3.3/guide/kohana/routing#route-filters

  • @Zeelot3k Nice, thank you for pointing that out, those routes isn't cacheable I assume?

  • not if you use a lambda, but I think it is cacheable if you use any other callback (like an array)

  • How REST APIs directory structure should look like?

    Is this even close?

    app/
      v1/
        controllers/
          c1
          c2
        models/
          m1
          m2
        views/
          view1
          view2
      v2/
        controllers/
          c1
          c2
        models/
          m1
          m2
        views/
          view1
          view2
    
  • Why separate the vhole app?

    app/
      classes/
        controller/
          api/
            v1/ // maybe you can decide the version in the controller class eg. in Controller_Api passed from the route callback
            v2/
        model/
          // sure you need new/other models?
        view/
          // how they called from controllers
    
  • @dyron I like the idea that only Controllers are separated to version directories.

    How do you add CRUD to structure?

    CRUD === Actions?

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion