Currently we have a widespread issue on our codebase, our frontend components do not expose interfaces to express the nature of what they expect as input.
This prevents us from having a centralized input validation mechanism shared by our components, which makes them extremely fragile, if the data received is not the one initially expected.
We have therefore taken the bad habit of being overly defensive by default in the templates to avoid breaking errors at rendering time.
Indeed today a small payload change in a third party api, transmitted as is by our back-for-front to the rendering engine could break the whole app.
To avoid confusion please note the following differences:
componentId
refers to the so-called "engine" componentscomponent
refers to the (svelte) frontend implementationThe registry maps engine components to their implementation in the app.
The idea is to store in a centralized registry a mapping between engine identifiers and their associated implementation and inputs validation schemas.
If you want to make a component eligible to this new way of doing, you must absolutely register it and declare a schema that will be used to validate at runtime that the data passed are valid, it is therefore to define a contract at registration. If the data entered do not respect the contract then the component will not be rendered (an error could be rendered instead).
To force this centralized validation, we introduce a Safe
component whose mission is to take an engine input (componentid / data) and to render it if possible using the implementations at our disposal via the centralized registry.
App
represents a fictitious applicationregistry
is the service that exposes the engine-implem mapping (get/register)registration
is the place where we register one by one our implementation (creation of the mapping)To register a component
import { register } from './registry.js';
import Hello from './path/to/Hello.svelte';
const hello_inputs_schema = {
type: 'object',
properties: {
what: { type: 'string' },
},
required: ['what'],
};
register('hello_id', hello_inputs_schema, Hello);
To display a registered component you can now do
<Safe engineId="hello_id" data={ { what: 'world' } } />
Hello
will be rendered with the what
prop set to 'hello'
If you try with invalid data
<Safe engineId="hello_id" data={ { bad: 'world' } } />
The Hello component will not be rendered and an error (generated by ajv) will tell you that you miss the what
property
git clone https://github.com/xavhan/safe-components
cd safe-components
npm install
npm run dev