FluidFramework
FluidFramework copied to clipboard
OdspClient: Support more extensive app scenarios (Designer app)
Scenario/ success criteria
The goal of it is to enable more scenarios for OdspClient, in particular - enable scenarios that Designer app needs, and scenarios that they will likely need in nearest future (based on our experience with another Odsp app - Loop).
- Leverage our declarative model (mostly this is about SharedTree).
- Successfully implement the following scenarios (in priority order):
- Store FF content in alternate partitions. Designer will follow SPO Pages design and store FF data not in main partition of a file, but in alternate partition of SharePoint file. This difference is mostly transparent for FF layers (as SharePoint redirects all calls to such partition, based on file extension), but creation flow differs - instead of file name, we need to pass itemId of existing file.
- Support CLP (i.e. clp-compliant apps need to pass extra header).
- Expose ODSP driver policies and capabilities, including provide ability for the app to use caching layer.
- Enable sharing flow and working with sharing links, including single roundtrip scenarios
- Properly expose types & signatures of the APIs: IFluidContainer.attach() should have proper type and reflect the input parameter type (broken today).
Reframing in Fluid language
The problem is - how do we expose rich set of scenarios that ODSP driver supports, in a way that is
- Easily discoverable
- Self documenting
- And ideally - can be leveraged using our declarative API model (i.e. using OdspClient), with an eye toward learning and taking this knowledge / direction to encapsulated model as well.
Sharing workflow & Design choices
We provide a set of URI resolvers that make it easier for the application to work with SharePoint canonical and sharing links. Canonical links are not controlled by the application, and thus there some value in providing common tools to deal with that. Sharing links are a bit more nuanced, as applications could (depending on scenarios) add their own payloads (nav
parameter) and construction of such payload could be app specific. It's not possible to work efficiently with sharing links without having file identity information that is usually encoded in such nav parameter.
On top of that dealing with URIs and URI resolves is extremely hard - the protocol / types are not in clear sight, it's extremely hard to learn what functionality exists or functionality app has to use.
As such, I chose to build and expose IOdspCreateRequest
& IOdspOpenRequest
(see here) interfaces that describe all the functionality that ODSP driver exposes and provide adapters to convert them to existing flows (based on IOdspResolvedUrl used across the driver). This way clients could
- encode & decode URIs on their own, fully controlling their format
- have type-safe interaction with FF
- know all the functionality available or required from the app.
This does not eliminate us providing stock implementations for various common flows, like parsing or generating canonical links.
Compatibility considerations
This prototype explores what it takes to make existing OdspClient flows to support scenarios outlined above. It goes without saying that it will be breaking change if we go that route (and we will need to introduce these breaks ASAP), and the only issue is - how breaking.
That said, we could also abandon OdspClient as is and create OdspClient2. Or push Designer (and any new app that is in similar need) toward using loader + odsp driver. That said, even if we go loader + odsp driver, it's not wasted effort, as it's really hard to figure out contracts in the system hiding behind IRequest opaque interface. Part of this work is discovery and figuring out what typical app needs, and thus having right inputs into decision tree.
The other aspect to consider - these changes impact AzureClient. There are options here, but if we absolutely do not want to change any type touching AzureClient, we likely need a bigger fork (I've tried to preserve as much of shared types here as possible between AFR and ODSP flows).
Where to start with review
- packages/drivers/odsp-driver-definitions/src/resolvedUrl.ts - newly created ODSP interfaces
- packages/framework/fluid-static/src/fluidContainer.ts - common code between various clients, parametrization of various interfaces to properly support customized flows.
- packages/service-clients/odsp-client/src/interfaces.ts has most of the changes (types) for OdspClient flow.
- packages/service-clients/odsp-client/src/odspClient.ts demonstrates actual flows (encoding / decoding sharing links, etc.)
Open questions / Questionable flows
- It's a bit weird to provide driveId & siteURI when container open flow is based on sharing link and thus does not use this info - it gets identity of the file from sharing link. Maybe we move it out into stand-alone API (to create container from sharing link)?
- I downgraded some OdspClient types from @ beta to @ alpha, as I have to take dependency on a bunch of @ alpha types. We can upgrade them all to beta
What is not done
- Test everything
- sharing flow
- alt partition flow
- There are a number of eslint-disable-next-line import/no-internal-modules rules to import from @fluidframework/odsp-client/internal - need to add proper projects into exception list.