Overriding forms-engine-plugin logic with custom services
Customising where forms are loaded from
The engine plugin registers several routes on the hapi server.
They look like this:
GET /{slug}/{path}POST /{slug}/{path}A unique slug is used to route the user to the correct form, and the path used to identify the correct page within the form to show.
The plugin registration options have a services setting to provide a formsService that is responsible for returning form definition data.
WARNING: This below is subject to change
A formsService has two methods, one for returning formMetadata and another to return formDefinitions.
const formsService = { getFormMetadata: async function (slug) { // Returns the metadata for the slug }, getFormDefinition: async function (id, state) { // Returns the form definition for the given id }}The reason for the two separate methods is caching.
formMetadata is a lightweight record designed to give top level information about a form.
This method is invoked for every page request.
Only when the formMetadata indicates that the definition has changed is a call to getFormDefinition is made.
The response from this can be quite big as it contains the entire form definition.
Loading forms from files
To create a formsService from form config files that live on disk, you can use the FileFormService class.
Form definition config files can be either .json or .yaml.
Once created and files have been loaded using the addForm method,
call the toFormsService method to return a FormService compliant interface which can be passed in to the services setting of the plugin options.
import { FileFormService } from '@defra/forms-engine-plugin/file-form-service.js'
// Create shared form metadataconst now = new Date()const user = { id: 'user', displayName: 'Username' }const author = { createdAt: now, createdBy: user, updatedAt: now, updatedBy: user }const metadata = { organisation: 'Defra', teamName: 'Team name', teamEmail: 'team@defra.gov.uk', submissionGuidance: "Thanks for your submission, we'll be in touch", notificationEmail: 'email@domain.com', ...author, live: author}
// Instantiate the file loader form serviceconst loader = new FileFormService()
// Add a Json formawait loader.addForm( 'src/definitions/example-form.json', { ...metadata, id: '95e92559-968d-44ae-8666-2b1ad3dffd31', title: 'Example Json', slug: 'example-json' })
// Add a Yaml formawait loader.addForm( 'src/definitions/example-form.yaml', { ...metadata, id: '641aeafd-13dd-40fa-9186-001703800efb', title: 'Example Yaml', slug: 'example-yaml' })
// Get the forms serviceconst formsService = loader.toFormsService()