Skip to content
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

Split URL building from HTTP handling? #65

Open
natevw opened this issue Oct 16, 2017 · 2 comments
Open

Split URL building from HTTP handling? #65

natevw opened this issue Oct 16, 2017 · 2 comments

Comments

@natevw
Copy link
Owner

natevw commented Oct 16, 2017

Looking over #49 again it strikes me that perhaps folding the "method methods" (.get(cb)/.put(data, cb)/etc.) into the same namespace as the URL path components has sort of boxed us in re. things like clean Promise support.

Conceptually Fermata is two parts:

  • a "syntax" for building URLs
  • an HTTP request library

Perhaps they would be useful as separate pieces; when bundled together they'd hinge around the empty () call that currently just returns a string. You'd still build a URL with the current tricks var url = base.api.path.to('some-thing', {s:}) and have the nice HTTP plugin stack via .put({foo:42}, function (err, data, meta) { … }) pattern — but you'd need the () between your URL and the HTTP methods: url().get(cb).

One catch would be how to control the HTTP "plugin stack" apart from the URL. I think we could handle that by still allowing functions to be passed to the () — only now the function would be the HTTP plugin rather than the cb. Something like:

var f = require('fermata');

var serverUrl = f.url("https://example.com"),
    widgetsUrl = serverUrl.api({v:1}).user[name].widgets;

/*                          \         / <--- passing a plugin function
var widgetsHttp = widgetsUrl(f.PROMISE);
widgetsHttp.get().then(function (d) {
  // …
});

This isn't something I want to do lightly, because it's something of a fundamental shift in what Fermata is. How would this affect "wrappers" like fermata-couchdb with its var db = fermata.couchdb()('my-database')?

I've tried to position Fermata as the "un-wrapper for X", where X is any web API. Rather than wrapping [CouchDB]((https://github.com/natevw/fermata-couchdb), Twitter, Flickr, Chargify, etc. etc. each with their own special wrapper that tries to paper over the underlying API — often nearly re-inventing, then re-documenting it — Fermata provides plugins to set up the basics like JSON and OAuth, but otherwise leaves the server API as the JavaScript API.

Would splitting the "URL stuff" from the "HTTP stuff" jeopardize the "web API not-a-wrapper" goal?

@natevw
Copy link
Owner Author

natevw commented Jan 18, 2018

Wouldn't this address #28 too?

@natevw
Copy link
Owner Author

natevw commented Jan 18, 2018

As a solution to the plugin dilemma of the initial idea, perhaps the URL objects can be "pre-annotated" by a plugin?

The proposal here is basically that () returns a wrapper around the underlying transport. That transport can be an implicit part of the URL object, right?

E.g. if you create a URL using a plugin that includes OAuth or other special headers, that URL gets associated from the get-go with a transport plugin. The challenge then is simply what the "core API" would looks like for a plugin to make this association.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant