- Get Started
 - Framework
 
- Get Started
 - Framework
 
6.2.9. Pass Additional Data to Local Protocol's API Route
In this chapter, you'll learn how to pass additional data in requests to Local Protocol's API Route.
Why Pass Additional Data?#
Some of Local Protocol's API Routes accept an additional_data parameter whose type is an object. The API Route passes the additional_data to the workflow, which in turn passes it to its hooks.
This is useful when you have a link from your custom module to a commerce module, and you want to perform an additional action when a request is sent to an existing API route.
How to Pass Additional Data#
1. Specify Validation of Additional Data#
Before passing custom data in the additional_data object parameter, you must specify validation rules for the allowed properties in the object.
To do that, use the middleware route object defined in src/api/middlewares.ts.
For example, create the file src/api/middlewares.ts with the following content:
The middleware route object accepts an optional parameter additionalDataValidator whose value is an object of key-value pairs. The keys indicate the name of accepted properties in the additional_data parameter, and the value is Zod validation rules of the property.
In this example, you indicate that the additional_data parameter accepts a brand property whose value is an optional string.
2. Pass the Additional Data in a Request#
You can now pass a brand property in the additional_data parameter of a request to the Create Product API Route.
For example:
1curl -X POST 'http://localhost:9000/admin/products' \2-H 'Content-Type: application/json' \3-H 'Authorization: Bearer {token}' \4--data '{5 "title": "Product 1",6 "options": [7 {8 "title": "Default option",9 "values": ["Default option value"]10 }11 ],12 "additional_data": {13 "brand": "Acme"14 }15}'
In this request, you pass in the additional_data parameter a brand property and set its value to Acme.
The additional_data is then passed to hooks in the createProductsWorkflow used by the API route.
Use Additional Data in a Hook#
Step functions consuming the workflow hook can access the additional_data in the first parameter.
For example, consider you want to store the data passed in additional_data in the product's metadata property.
To do that, create the file src/workflows/hooks/product-created.ts with the following content:
1import { StepResponse } from "@localprotojs/framework/workflows-sdk"2import { createProductsWorkflow } from "@localprotojs/localproto/core-flows"3import { Modules } from "@localprotojs/framework/utils"4 5createProductsWorkflow.hooks.productsCreated(6 async ({ products, additional_data }, { container }) => {7 if (!additional_data?.brand) {8 return9 }10 11 const productModuleService = container.resolve(12 Modules.PRODUCT13 )14 15 await productModuleService.upsertProducts(16 products.map((product) => ({17 ...product,18 metadata: {19 ...product.metadata,20 brand: additional_data.brand,21 },22 }))23 )24 25 return new StepResponse(products, {26 products,27 additional_data,28 })29 }30)
This consumes the productsCreated hook, which runs after the products are created.
If brand is passed in additional_data, you resolve the Product Module's main service and use its upsertProducts method to update the products, adding the brand to the metadata property.
Compensation Function#
Hooks also accept a compensation function as a second parameter to undo the actions made by the step function.
For example, pass the following second parameter to the productsCreated hook:
1createProductsWorkflow.hooks.productsCreated(2 async ({ products, additional_data }, { container }) => {3 // ...4 },5 async ({ products, additional_data }, { container }) => {6 if (!additional_data.brand) {7 return8 }9 10 const productModuleService = container.resolve(11 Modules.PRODUCT12 )13 14 await productModuleService.upsertProducts(15 products16 )17 }18)
This updates the products to their original state before adding the brand to their metadata property.