FamilySearch / fs-js-lite

Lite JS SDK for the FamilySearch API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Disable default middleware

justincy opened this issue · comments

We're almost done with #2 adding middleware. It has been a much more fruitful enterprise than I expected.

As part of that, the sdk sets up default request and response middleware to handle throttling, redirects, Authorization header, default Accept header, and more. It could be useful to provide a method for disabling some of the default middleware.

Idea 1: Options

Allow for the middleware to be disabled via the options when instantiating an SDK instance.

var client = FamilySearch({
    handleThrottling: false
});

Idea 2: Middleware Stacks

This idea comes from Guzzle with has Handlers and HandlerStacks (combination of a handler and middleware stacks).

This would give developers more control over middleware.

We learned in #15 that we likely don't need a way to disable any of the default middleware outright but instead could selectively enables its behavior on request via the request options.

client.get('/platform/tree/current-person', {
    expectRedirect: true,
    followRedirect: true
});

We've previously identified that redirects are the only middleware you might not want in node so I believe those two options would solve the issue for now.

But for the request options to work they would need to be accessible to the middleware. That's currently not the case. The SDK generates an internal request object that is given to the middleware and that object picks out pieces of data from the request options provided by the user so any custom options are effectively dropped (an unintentional consequence of the design).

I see a few ways of making the original request options available to middleware:

  1. Include the original request options in the internal Request object as Request.options.
  2. Get rid of the internal Request class and thus pass the original request options directly to middleware. The Request class was originally created to centralize the pre-processing of request options but that's since been moved to middleware. There are a still a few useful methods left but it wouldn't be too painful to remove them.
  3. Support an options, custom, or middlewareOptions property on the request options object where we stuff all custom options for middleware.
  4. Automatically copy all properties with a certain prefix such as _. This is a ridiculous variant of option 3.

I'm not a fan of adding more middleware parameters. Request middleware already has 3 parameters and response middleware has 4. I prefer having the options made available via the request object.

I don't want to get rid of the internal Request class. I prefer adding an options object to Request. The naive approach would also involve changing our example to

client.get('/platform/tree/current-person', {
    options: {
        expectRedirect: true,
        followRedirect: true
    }
});

but I don't like that. I prefer the original example without the options attribute. Thus Request must iterate over known properties and stuff anything else into it's internal options list.