Monetization Programmatic Quotas

When adding monetization to your API, you would usually set the number of meters a request will consume in the settings of the Monetization Policy. For example, the policy below specifies that each request will consume 1 requests meter and 5 computeUnits meters.

{ "export": "MonetizationInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "allowRequestsOverQuota": false, "allowedSubscriptionStatuses": ["active", "incomplete"], "meterOnStatusCodes": "200-399", "meters": { "requests": 1, "computeUnits": 5 } } }

However, in some cases, you may not know up front how many units of a particular meter will be consumed until after the response is sent. For example, maybe your backend is responsible for computing the computeUnits on a request and send the result in the response in the compute-units header.

In Zuplo, you can support these dynamic meters by writing a little code. To make the computeUnits meter dynamic, first update the policy by setting the computeUnits meter to 0 as shown below.

{ "export": "MonetizationInboundPolicy", "module": "$import(@zuplo/runtime)", "options": { "allowRequestsOverQuota": false, "allowedSubscriptionStatuses": ["active", "incomplete"], "meterOnStatusCodes": "200-399", "meters": { "requests": 1, "computeUnits": 0 } } }

Next you can create a custom code outbound policy that reads data from the Response (in this case the compute-units header) and sets the meter programmatically.

import { MonetizationInboundPolicy, ZuploRequest, ZuploContext, } from "@zuplo/runtime"; export default async function ( response: Response, request: ZuploRequest, context: ZuploContext, options: any, policyName: string, ) { const headerValue = response.headers.get("compute-units"); let computeUnitsValue; if (headerValue && typeof headerValue === "string") { computeUnitsValue = parseInt(headerValue); } // Throw an error if the server doesn't send compute units // Alternatively, you could have a default value if (!computeUnitsValue) { throw new Error("Invalid response, no compute units sent."); } // Set the compute units for the request MonetizationInboundPolicy.setMeters(context, { computeUnits: computeUnitsValue, }); return response; }