What's the best way to implement prototype patterns in Zapier integrations?

I’m building a custom integration for Zapier and my code is getting really messy. I have tons of similar functions that do almost the same thing but with different endpoints and parameters. I keep copying and pasting the same logic over and over.

Is there a way to use JavaScript prototypes to clean this up? I want to create some kind of base object that I can extend for different API calls. Right now I have something like this:

var ApiHandler = {
    product_data_fetch: function(config) {
        var apiResponse = JSON.parse(config.response.content);
        apiResponse.items.reverse();
        
        // fetch additional data
        var requestObj = {
            'url': "api.example.com/v1/" + config.auth_fields.company_id + 
                "/products/details(id='" + apiResponse.items[i].product_id + "')?format=json",
            'headers': {
                "Authorization": "Bearer " + btoa(config.auth_fields.user + ':' + config.auth_fields.pass)
            },
            'method': "GET"
        };
        var detailResponse = z.request(requestObj);
        
        try {
            var parsedData = JSON.parse(detailResponse.content);
            apiResponse.items[i].product_title = parsedData.Name;
        } catch(err) {
            console.log(err);
            apiResponse.items[i].product_title = apiResponse.items[i].default_name;
        }
        
        return apiResponse;
    }
}

How can I make this more reusable?

I hit the same issue building Zapier integrations. Constructor functions with prototypes work way better than object literals here. Skip your current approach and create a base ApiHandler constructor for common auth and request logic, then extend it for specific endpoints. Try function ApiHandler(config) { this.config = config; } then add shared methods to ApiHandler.prototype for stuff like auth headers and error handling. For products or orders handlers, make new constructors that inherit from the base using Object.create(ApiHandler.prototype). You can override specific methods while keeping common request patterns. Zapier’s execution context loves this pattern - each trigger/action gets its own instance and you ditch all that messy copying.

You’re overcomplicating this with object literals. I set up a base prototype that handles the common request flow, then used Object.setPrototypeOf() to chain specific handlers. Put your auth logic and error handling in the base prototype. Endpoint-specific stuff goes in child objects. Do something like BaseHandler.prototype.makeRequest = function() { /* common request logic */ } then create specific handlers that inherit from it. Here’s the thing - Zapier’s z.request calls are expensive, so prototype methods let you standardize request building and response parsing without duplicating HTTP logic. I cut my integration from 800+ lines down to about 200 by moving shared response parsing into prototype methods.

Just go with ES6 classes if Zapier supports them - way cleaner than dealing with prototype chains. Make a base ApiClient class for your auth and request stuff, then extend it for different endpoints. class ProductHandler extends ApiClient works perfectly and you can override whatever you need. Way simpler inheritance without the Object.create mess.