{"id":17181,"library":"btrz-http-service","title":"Betterez HTTP Service Utilities","description":"btrz-http-service is a JavaScript utility library designed to streamline API development within the Betterez ecosystem. Currently at version 1.47.0, it offers a suite of tools including a Swagger request handler formatter for defining API endpoints, specialized success and error response handlers for consistent API feedback, a collection of common Swagger schemas, and robust Swagger schema validation. It also introduces a custom `ValidationError` type to standardize error reporting within the application. The library appears to be actively maintained with a steady release cadence, evidenced by its significant minor version increments. Its key differentiators include its tight integration with Swagger for API definition and validation, a structured approach to middleware and error handling, and its focus on providing consistent API behavior for Betterez applications.","status":"active","version":"1.47.0","language":"javascript","source_language":"en","source_url":"https://github.com/Betterez/btrz-http-service","tags":["javascript","request","response","handlers","http"],"install":[{"cmd":"npm install btrz-http-service","lang":"bash","label":"npm"},{"cmd":"yarn add btrz-http-service","lang":"bash","label":"yarn"},{"cmd":"pnpm add btrz-http-service","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used for validating request bodies against Swagger schemas, as indicated by release notes and `validateSwaggerSchema` utility.","package":"swagger-validation","optional":false},{"reason":"The README describes middleware functions with a `(req, res, next)` signature and mentions 'Just like in Express with Connect,' implying an Express.js-like environment.","package":"express","optional":true},{"reason":"Mentioned in code examples (`passportAuthenticate`) and related Betterez package documentation, suggesting common integration for authentication.","package":"btrz-auth-api-key","optional":true}],"imports":[{"note":"The documentation explicitly uses CommonJS `require`. Direct ESM import syntax might not be supported without a transpilation step or if the package is purely CJS.","wrong":"import { swaggerRequestHandler } from 'btrz-http-service';","symbol":"swaggerRequestHandler","correct":"const swaggerRequestHandler = require('btrz-http-service').swaggerRequestHandler;"},{"note":"Provides `success` and `error` methods for standardizing API responses. Intended for use at the end of promise chains.","wrong":"import { ResponseHandlers } from 'btrz-http-service';","symbol":"ResponseHandlers","correct":"const ResponseHandlers = require('btrz-http-service').ResponseHandlers;"},{"note":"This function is used for runtime validation of request bodies against defined Swagger schemas.","wrong":"import { validateSwaggerSchema } from 'btrz-http-service';","symbol":"validateSwaggerSchema","correct":"const validateSwaggerSchema = require('btrz-http-service').validateSwaggerSchema;"},{"note":"A custom error type subclassing native `Error`, allowing for specific error codes, messages, and HTTP status overrides for API responses.","wrong":"import { ValidationError } from 'btrz-http-service';","symbol":"ValidationError","correct":"const ValidationError = require('btrz-http-service').ValidationError;"}],"quickstart":{"code":"const { swaggerRequestHandler, ResponseHandlers } = require('btrz-http-service');\n\n// A mock request object for demonstration\nconst mockReq = { body: { items: ['item1', 'item2'] } };\n// A mock response object with methods expected by ResponseHandlers\nconst mockRes = {\n  statusCode: 200,\n  data: null,\n  status(code) { this.statusCode = code; return this; },\n  send(data) { this.data = data; console.log(`Response Status: ${this.statusCode}, Data:`, this.data); },\n  json(data) { this.data = data; console.log(`Response Status: ${this.statusCode}, JSON:`, this.data); },\n};\n\nclass RequestHandler {\n  constructor(swagger) {\n    this.swagger = swagger; // In a real app, this might be injected or provided\n  }\n  getSpec() {\n    return {\n      \"description\": \"endpoint description\",\n      \"path\": \"/endpoint\",\n      \"summary\": \"endpoint summary\",\n      \"method\": \"POST\",\n      \"parameters\": [\n        {\n          \"name\": \"items\",\n          \"in\": \"body\",\n          \"description\": \"the items\",\n          \"schema\": { \"type\": \"array\", \"items\": { \"type\": \"string\" } },\n          \"required\": true\n        }\n      ],\n      \"produces\": [\"application/json\"],\n      \"type\": \"Schema\",\n      \"errorResponses\": [],\n      \"nickname\": \"nick\"\n    };\n  }\n  async handler(req, res) {\n    console.log('Handler received request body:', req.body);\n    try {\n      // Simulate an async operation\n      await new Promise(resolve => setTimeout(resolve, 100));\n      if (!req.body || !Array.isArray(req.body.items) || req.body.items.length === 0) {\n        throw new Error('No items provided');\n      }\n      const processedData = req.body.items.map(item => item.toUpperCase());\n      console.log('Processed data:', processedData);\n      // Use success handler\n      ResponseHandlers.success(res)(processedData);\n    } catch (error) {\n      console.error('Handler error:', error.message);\n      // Use error handler\n      ResponseHandlers.error(res)(error);\n    }\n  }\n}\n\n// Mock middleware for demonstration\nfunction passportAuthenticate(req, res, next) {\n  console.log('Running passportAuthenticate middleware');\n  // Simulate authentication success\n  next();\n}\n\nfunction otherMiddleware(req, res, next) {\n  console.log('Running otherMiddleware');\n  // Simulate some other processing\n  next();\n}\n\n// Create a handler instance (mocking swagger object as it's not provided in context)\nconst handlerInstance = new RequestHandler({}); \n\n// Generate the swagger handler with middleware\nconst swaggerHandler = swaggerRequestHandler(passportAuthenticate, otherMiddleware, handlerInstance);\n\n// Simulate calling the generated swaggerHandler\nconsole.log('--- Simulating API Call ---');\nswaggerHandler(mockReq, mockRes);","lang":"javascript","description":"This quickstart demonstrates how to define an API endpoint using a `RequestHandler` class, integrate it with `swaggerRequestHandler` and optional middleware, and handle responses using `ResponseHandlers.success` and `ResponseHandlers.error`."},"warnings":[{"fix":"Upgrade to `btrz-http-service` v1.6.6 or newer, which includes a workaround to clone the `models` object before validation. Ensure your application does not rely on mutable `models` objects if using older versions.","message":"Older versions (v1.6.5 and earlier) of `btrz-http-service` used `swagger-validation` in a way that could mutate the original Swagger `models` object passed for validation. This could lead to unexpected side effects in applications that reuse the models.","severity":"gotcha","affected_versions":"<1.6.6"},{"fix":"Always place `ResponseHandlers.success(res)` or `ResponseHandlers.error(res)` as the final `.then()` or `.catch()` callback in your promise chains to ensure a single, consistent response.","message":"The `ResponseHandlers.success` and `ResponseHandlers.error` utilities are designed to be used only once at the very end of a promise chain. Calling them multiple times or at intermediate steps in a chain can lead to unexpected behavior or errors in API responses.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure that the `RequestHandler` instance is correctly initialized with a `swagger` object that contains the necessary properties, such as `paramTypes`, as expected by the `getSpec` method. This object is typically provided by the framework integrating `btrz-http-service`.","message":"When defining `getSpec()` in a `RequestHandler` class, ensure that `this.swagger.paramTypes` or other `this.swagger` properties are correctly initialized and available. Improper setup of the `swagger` object passed to the `RequestHandler` constructor can lead to `TypeError: Cannot read properties of undefined (reading 'paramTypes')`.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure that the `RequestHandler` class is properly constructed with a `swagger` object that provides the `paramTypes` utility, or mock it during testing. In typical usage, an integrating framework provides this context.","cause":"`this.swagger` or `this.swagger.paramTypes` is undefined within a `RequestHandler`'s `getSpec` method.","error":"TypeError: Cannot read properties of undefined (reading 'paramTypes')"},{"fix":"Check the API documentation for the endpoint's schema requirements. Adjust the request payload to include all required fields and ensure data types and formats match the schema definition. The `WRONG_DATA` log entry should specify the model path and field value.","cause":"A request body failed validation against its defined Swagger schema, indicating missing or invalid data.","error":"ValidationError: WRONG_DATA - The 'field_name' field is required."},{"fix":"Review the code to ensure that only one response is sent per request. Pay close attention to asynchronous operations and promise chains, especially when using `ResponseHandlers.success` and `ResponseHandlers.error`, which should be terminal operations.","cause":"Multiple attempts were made to send a response (e.g., using `res.send`, `res.json`, or a response handler) within a single request-response cycle, likely due to incorrect promise chaining or conditional logic.","error":"ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client"}],"ecosystem":"npm","meta_description":null}