natevw / fermata

Succinct native REST client, for client-side web apps and node.js. Turns URLs into (optionally: magic!) JavaScript objects.
328 stars 24 forks source link

Implement path rewriting #54

Closed Shmiddty closed 8 years ago

Shmiddty commented 9 years ago

Ideally this would be a module, though it seems that would require a change in the module api. Currently I'm modifying the fermata wrapper post-initialization.

transport.using("theModule", {
  "foo": "api/foosball",
  "bar": "api/foosball/barbacoa",
  "baz": "api/foosball/barbacoa/bazaar"
});

or

transport.using("theModule", {
  "foo": { "/": "api/foosball",
    "bar": { "/": "./barbacoa",
      "baz": { "/": "./bazaar" }
    }
  }
});

This is especially useful for APIs that have url patterns that are awkward or incompatible with property accessors:

"sprockets": "api/widgets:sprockets/",
"fooBar": "api/foo-bar/",
"bux": "api/{buxid}/list"

Furthermore, this would allow pre-populating of property accessors in instances where the Proxy api is not available.

natevw commented 8 years ago

Thanks for posting this issue and sorry it's taken me so long to even respond :-/

This is something that would benefit from a solution to #30, but I think it's already possible. For example, if you wanted to add rewriting to the JSON plugin, you could do something like this:

fermata.registerPlugin('someService', function (transport, apiKeyOrWhatever) {
    function rewrite(str) {
      return /* TODO: your fixed up path */;
    }

    this.base = "https://"+apiKeyOrWhatever+"@myapi.example.com";
    transport = transport.using('statusCheck').using('autoConvert', "application/json");
    return function (req, cb) {
        req.path = rewrite(req.path);
        return transport(req, cb);
    };
});

var myApi = fermata.someService("AP1K3Y");
// …

Would that accomplish some of your goals here? It wouldn't help you pre-populate property accessors, and really this might not be the best use of Fermata anyway.

What I mean is, Fermata is designed to make nearly "direct" use of an API and its documentation possible. For a plugin to do small helpful stuff like auto-generating a base URL or including some special header or opt into OAuth or whatnot is "normal" and fits this design. So would a "generic" mapping of any XML response from the API into some standard object shape.

What's not really a great fit for Fermata plugins is things like URL rewriting, or converting objects differently in all sorts of special cases. The reason being, now you have to document all these special rules and cases. In a situation like this, I think you'd be better off writing a wrapper for your server's API. (I'd be honored if you chose to use fermata internally, but to your user it wouldn't matter much since there'd be no direct access.)


I hope this helps you or someone else encountering the problem! I'm going to close but feel free to re-open if you have followup questions or want to push back that this is something Fermata should support. Thanks again!