{"id":16049,"library":"hapi-api-version","title":"Hapi API Versioning Plugin","description":"hapi-api-version is a plugin designed for the Hapi.js framework (v17 onwards) to facilitate API versioning. It allows developers to manage different API versions by supporting versioning via the `Accept` header or a custom header (defaulting to `api-version`). The plugin internally rewrites URLs based on the requested API version, enabling both handler-only versioning and distinct route definitions per version, including separate response schemas. The latest version, 2.3.1, was last published 7 years ago, making it compatible only with older Hapi.js ecosystems (specifically Hapi v17.x). It does not receive active updates for modern Hapi versions (v20+ or v21+), implying a halted release cadence and limited applicability for current Hapi projects.","status":"abandoned","version":"2.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/p-meier/hapi-api-version","tags":["javascript","hapi","hapijs","api","versioning"],"install":[{"cmd":"npm install hapi-api-version","lang":"bash","label":"npm"},{"cmd":"yarn add hapi-api-version","lang":"bash","label":"yarn"},{"cmd":"pnpm add hapi-api-version","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, required for the plugin to function within a Hapi.js server. Specifically targets Hapi v17.x.x.","package":"@hapi/hapi","optional":false}],"imports":[{"note":"This plugin is CJS-only and primarily intended for direct registration with a Hapi server. It does not export named members. Modern Hapi versions (v20+) support ESM, but this plugin does not.","wrong":"import hapiApiVersion from 'hapi-api-version';","symbol":"hapiApiVersion","correct":"const hapiApiVersion = require('hapi-api-version');"},{"note":"The plugin is registered as an object with a `plugin` key referencing the required module, and an `options` object for configuration.","wrong":"await server.register(hapiApiVersion, { options: { validVersions: [1, 2] } });","symbol":"Plugin Registration","correct":"await server.register({ plugin: require('hapi-api-version'), options: { validVersions: [1, 2], defaultVersion: 2, vendorName: 'mysuperapi' } });"}],"quickstart":{"code":"'use strict';\n\nconst Hapi = require('@hapi/hapi');\nconst hapiApiVersion = require('hapi-api-version');\n\nconst init = async function () {\n    try {\n        const server = new Hapi.server({ port: 3000 });\n        await server.register({\n            plugin: hapiApiVersion,\n            options: {\n                validVersions: [1, 2],\n                defaultVersion: 2,\n                vendorName: 'mysuperapi'\n            }\n        })\n\n        server.route({\n            method: 'GET',\n            path: '/users',\n            handler: function (request, h) {\n                const version = request.pre.apiVersion;\n                if (version === 1) {\n                    return [{ name: 'Peter Miller' }];\n                }\n                return [{ firtname: 'Peter', lastname: 'Miller' }];\n            }\n        });\n\n        server.route({\n            method: 'GET',\n            path: '/loginStatus',\n            handler: function (request, h) {\n                return { loggedIn: true };\n            }\n        });\n\n        await server.start();\n        console.log('Server running at:', server.info.uri);\n    }\n    catch (err) {\n        console.error('Server startup error:', err);\n        process.exit(1);\n    }\n};\n\ninit();","lang":"javascript","description":"This quickstart demonstrates setting up a Hapi server, registering the hapi-api-version plugin with basic options, and defining both versioned and unversioned routes. It shows how to access the detected API version from `request.pre.apiVersion` to serve different data based on the client's requested version."},"warnings":[{"fix":"For modern Hapi.js (v20+), consider alternative API versioning strategies or a different plugin. Migrating to a newer Hapi version will require finding a new versioning solution or implementing custom logic.","message":"This plugin is strictly compatible with Hapi.js versions 17.x.x. It is not maintained for or compatible with newer Hapi versions (e.g., v20, v21+), which have introduced significant breaking changes and ESM support.","severity":"breaking","affected_versions":">=3.0.0 (with Hapi >= v18), current version (for Hapi >= v20)"},{"fix":"Ensure client applications send either an `Accept` header in the format `application/vnd.<vendorName>.v<version>+json` or a custom header like `api-version: <version>`. For example, `Accept: application/vnd.mysuperapi.v1+json` or `Api-Version: 1`.","message":"The plugin relies on `accept` headers (with `vendorName`) or a custom header (default `api-version`) to determine the requested API version. If neither is present, it defaults to the `defaultVersion` specified in the options. Clients must correctly provide one of these headers.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When defining version-specific routes, structure your `path` options to include the version (e.g., `/v{version}/resource`). The plugin will then map the unversioned incoming request to the correct internal versioned path.","message":"The `hapi-api-version` plugin achieves versioning by internally rewriting requested URLs (e.g., `/users` to `/v1/users`). Developers defining versioned routes must ensure their route paths match this rewritten format (e.g., `/v1/users` and `/v2/users`) for the plugin to function correctly.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Avoid using this package in new Hapi.js projects. For existing projects, consider migrating to a newer, actively maintained Hapi.js version and finding an alternative API versioning solution that is compatible with Hapi v20+ or v21+.","message":"The package `hapi-api-version` has not been updated in 7 years. Its last stable version (2.3.1) targets Hapi.js v17.x. This indicates the package is effectively abandoned and not maintained for contemporary Node.js or Hapi.js versions.","severity":"deprecated","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure you are using `@hapi/hapi` version `17.x.x` as a peer dependency, and that `server.register` is called with an object containing a `plugin` key set to the required module and an `options` key. Check Hapi's migration guide if moving between major versions.","cause":"Attempting to use a Hapi.js version incompatible with the plugin's API, or incorrect plugin registration syntax.","error":"Cannot read properties of undefined (reading 'register') or server.register is not a function"},{"fix":"Provide all required options (`validVersions` as an array of integers, `defaultVersion` as an integer within `validVersions`, and `vendorName` as a string) during plugin registration. Refer to the plugin's documentation for option specifics.","cause":"Missing or invalid required options during plugin registration, such as `validVersions`, `defaultVersion`, or `vendorName`.","error":"Error: Plugin options validation failed"},{"fix":"Wrap your `init` function call or the `server.start()` and `server.register()` calls in a `try...catch` block to properly log and handle errors during server initialization. Ensure the port is not already in use.","cause":"Hapi server startup or plugin registration failed silently due to an unhandled promise rejection, often related to port conflicts or other initialization errors.","error":"UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: X)"}],"ecosystem":"npm"}