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

Add support for subrequests #43

Closed
paul121 opened this issue Jan 26, 2021 · 2 comments
Closed

Add support for subrequests #43

paul121 opened this issue Jan 26, 2021 · 2 comments

Comments

@paul121
Copy link
Member

paul121 commented Jan 26, 2021

Why

The Drupal Subrequests module allows multiple, dependent or independent requests to be defined in a "blueprint". The blueprint is sent to the server in a single POST (or query string encoded GET request) to /subrequests, where the server performs each request and returns a single multipart/related response containing the result of each individual sub-request.

This enables more complex API operations to be completed in a single step. For example, creating a new asset and immediately creating a movement log to locate the asset. Subrequests would also help API users with creating Logs that have multiple quantities. This works by allowing response values in later requests via JSON Paths.

Implementation Details

  • Adding support for Subrequests to the client is nearly as easy as creating a new client.subrequests namesapce with a send(blueprint) method. Users can be responsible for building a valid Subrequests blueprint.

  • Each request in the blueprint only requires an action and url property. But in general, most subrequests to a farmOS server will require an Authorization header to be set as well (an additional permission is required for users to use the /subrequests endpoint). For DX, the farmOS client libraries could auto-fill the Authorization header of each individual request, unless one is already provided. Similarly, the base URL shouldn't need to be provided. The farmOS client could auto-fill this as value as well.

  • The body property that is need for sub-requests sending data, such as create or update actions, needs to be a serialized JSON string. This is something the client could handle as well.

  • By default Subrequests returns an HTML multipart/related response which is fairly complicated to parse (see https://www.drupal.org/project/subrequests/issues/3194286). BUT subrequests can also return a JSON response with the result of each sub-request keyed by requestId. To do this, the JSON format must be requested by adding the ?_format=json query parameter. I don't see a reason that users would want the HTML response, but we could support this by adding a format parameter that defaults to json, eg; client.subrequests.send(blueprint, format='html').

  • A nice addition would be for the farmOS clients to provide some "helper" methods for building a Subrequests blueprint. I think the main pain points for developers will be:

      1. Learning the syntax for building blueprints
      1. getting the correct API URL endpoint (this is largely why we have client.log.get() anyways)
      1. building correct body payloads that include correct JSON Path embeddings

Proposed resolution

  • Create a client.subrequests namespace with a client.subrequests.send(blueprint, format="json") method to submit blueprints to the server. Unless format="html" is specified, append the ?_format=json query parameter.
  • Auto-fill the Authorization header on each sub-request within the blueprint, unless the header is already set (allow NULL so that un-authenticated requests can be made). This is not necessary! Each sub-request is run in same session as the "master request".
  • Set the Accept and Content-Type headers to be application/vnd.api+json, unless the header is already set.
  • Introduce an api_endpoint or endpoint property for individual subrequests. If no url is provided, the endpoint will be appended to the base URL already configured on the client.
  • Check if the sub-request body is a string or an object. If an object is provided, serialize it as a JSON string.
  • Re: painpoints:
    • 1: Create Pydantic models that represent the Subrequest blueprint schema. These can be used in an objec-oriented way to both create, convert, validate, type-check and serialize the Subrequests blueprint.
    • 2: Extra: consider creating client.resource.endpoint(type, bundle, id=None, params=None) and client.log.endpoint(bundle, id=None, params=None) methods for building correct API endpoints that include IDs and query parameters.
    • 3: Extra: create helper methods for common tasks eg: client.subrequests.createLog(references = []) (tbd...)
@paul121 paul121 mentioned this issue Jan 26, 2021
@paul121
Copy link
Member Author

paul121 commented Jan 26, 2021

One clarification: Authorization headers are not needed for each individual sub-request. They are run in the same session as the initial request that is sent to /subrequests

paul121 added a commit that referenced this issue Jan 30, 2021
@paul121
Copy link
Member Author

paul121 commented Feb 2, 2021

Added this in v1.0.0-alpha.2: https://github.com/farmOS/farmOS.py/releases/tag/v1.0.0-alpha.2

2: Extra: consider creating client.resource.endpoint(type, bundle, id=None, params=None) and client.log.endpoint(bundle, id=None, params=None) methods for building correct API endpoints that include IDs and query parameters.

3: Extra: create helper methods for common tasks eg: client.subrequests.createLog(references = []) (tbd...)

I think these would be nice features but lets wait to add these until later on as use cases further develop.

@paul121 paul121 closed this as completed Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant