- 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.