-
Notifications
You must be signed in to change notification settings - Fork 5
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
External secondary instances: I/O support for jr:
URLs
#201
Comments
I was thinking if host application could just provide secondary attachments along with Form XML so engine doesn't have make network calls and deal with all the network related errors. I am saying this with the assumptions:
This is closer to the Option 1 presented above, except required attachments are resolved at the host application levle before anything else happens. |
I want to make sure to sum up a couple key conclusions from our discussion yesterday: Design choice: Option 1, possibly supplemented by Option 0.5We decided to go with Option 1. As a stretch goal, we may also include aspects of Option 0.5 as an additive aid to clients/host applications. We refined the proposed Option 1 interface. Putting aside naming (included here so the type will be valid syntax/highlighted as such), this is the interface we anticipate clients/host applications to provide for all form attachments: type FormAttachmentMapping = Record<`jr:${string}`, () => Promise<Response>>; Open for bikesheddy discussion: is there any openness to making this a As for the value side of the mapping, providing a thunk per resource:
We decided to represent each resource as a On engine invocation of form requests broadly (i.e. including media)While this design is primarily focused on support for external secondary instances, it has obvious implications for other form attachments. We discussed this, which was also raised in the above comment. We determined it makes sense for the engine to invoke all such requests, largely for reasons discussed in the last section. Notably, we expect that the engine will perform media requests earlier in a form session (either as part of form load, or perhaps immediately following resolution of the initial form state). Addendum to yesterday's discussion of this pointAs an additional point not covered yesterday, but which I think helps to bolster this decision: insofar as the engine expects clients/host applications to provide resource data, there's another very good reason for the engine to invoke requests, and in particular to for the engine to get those requests back as a
And the engine does need to access at least some resource data for media attachments, as they may be associated with node values. In the future, we might consider expanding this interface to provide multiple representations, such as something like |
This design issue is part of broader support for external secondary instances:
jr:
URLsThe intent in this issue is to decide on a direction for how we want to handle retrieval of form attachments generally, with specific goal of supporting external secondary instance functionality.
These are the pertinent aspects of the ODK XForms spec.
The issue will focus on the engine/client interface to support the retrieval of
jr:
URLs. As I tend to do for engine/client interface design, I will present a few options which we can choose from or iterate on. Implementation in the engine will be derived from there.Note: it is expected that the design we choose here will also lay groundwork for supporting other
jr:
URL use cases—i.e. media attachments—so I've tried to be mindful of that (as we should in discussion).Note: this issue does not currently address the
jr://instance/last-saved
virtual endpoint, but I believe nothing in any of the proposed options would block or impede that functionality, when we're ready to address it.Option 0: client/host application handles resource resolution
This is a true null option: in the narrowest sense, we could claim this work is already done with the provision of a
fetchResource
configuration option. This option is technically sufficient to satisfy the engine's spec responsibilities.How this would work:
fetchResource
with any external secondary instance'sjr:
URLfetchResource
option, the client is then responsible for resolving thatjr:
URL to the referenced resource, for the active form instancefetchResource
option, the engine will produce a well-defined error result (with errors to be discussed in a separate design)At least until we support offline mode (or any other functionality that would imply runtime-level caching/persistence), this would leave resource resolution entirely to clients.
This is sort of the opposite of a "pit of success" option, with its primary appeal being limited engine-side work for this aspect of the targeted feature.
Beyond obvious non-"pit of success" drawbacks, I'll specifically note that it's the most likely option to result in disparities and drift between clients. It's also likely to promote disparities/drift between different functionality which intersect with it.1
Option 0.1: engine does not handle this aspect at all
Another null option variant.
This would effectively mean that clients must resolve
jr:
URLs before initializing a form. They'd probably supply the resources asdata:
orblob:
URLs, substituted directly in the form definition provided by clients to the engine.This option does not appeal to me, but I think it's worth mentioning so we can make a thoroughly informed decision.
Option 0.5: engine provides resolution handler(s) for common cases
An extension of option 0, this is similar in spirit to the submission API proposal (#188), and some of the discussion ongoing there. The idea would be that we recognize one or more typical resource mapping schemes, and expose default
fetchResource
implementations to address those (likely as some kind of factory function so clients can parameterize them for per-instance usage appropriately).I would imagine starting with handlers for:
Option 1: engine provides one or more explicit mechanisms for form attachment resolution, tailored to feature-specific use cases
Instead of the engine calling a generalized
fetchResource
option with ajr:
URL, the engine would instead accept a configuration mapping between specificjr:
URLs to one of:fetch
-able URL (blob:
,data:
, ?); this mapped URL would then be accessed by the samefetchResource
optionBlob
of the resource's data (Promise<Blob>
,() => Promise<Blob>
, ?)The mapping itself could be any of:
Map
-like object (or evenRecord<string, T>
if we're feeling really loosey goosey about it)Footnotes
This has been a particular pain point in Enketo. Support for
jr:
URLs is spread across three packages, and difficult to iterate on even after moving the projects to a monorepo. ↩The text was updated successfully, but these errors were encountered: