{"id":19165668,"url":"https://github.com/loopbackio/loopback-connector-openapi","last_synced_at":"2026-03-12T04:31:03.026Z","repository":{"id":42966553,"uuid":"174879911","full_name":"loopbackio/loopback-connector-openapi","owner":"loopbackio","description":"LoopBack connector for OpenAPI spec (2.0 and 3.0.x) compliant services  ","archived":false,"fork":false,"pushed_at":"2024-08-25T17:52:39.000Z","size":284,"stargazers_count":8,"open_issues_count":5,"forks_count":4,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-10-19T05:53:19.526Z","etag":null,"topics":["hacktoberfest","loopback","nodejs","openapi"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loopbackio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-03-10T20:55:36.000Z","updated_at":"2024-08-25T17:52:43.000Z","dependencies_parsed_at":"2023-12-15T06:29:05.986Z","dependency_job_id":"ca4f6712-8778-4301-91c9-9e470ff18b6c","html_url":"https://github.com/loopbackio/loopback-connector-openapi","commit_stats":null,"previous_names":["strongloop/loopback-connector-openapi"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/loopbackio/loopback-connector-openapi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-openapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-openapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-openapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-openapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loopbackio","download_url":"https://codeload.github.com/loopbackio/loopback-connector-openapi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-openapi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30415449,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T04:25:42.844Z","status":"ssl_error","status_checked_at":"2026-03-12T04:25:34.624Z","response_time":114,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","loopback","nodejs","openapi"],"created_at":"2024-11-09T09:28:56.125Z","updated_at":"2026-03-12T04:31:02.985Z","avatar_url":"https://github.com/loopbackio.png","language":"JavaScript","readme":"# loopback-connector-openapi\n\nThe Swagger connector enables LoopBack applications to interact with other REST APIs described by the [OpenAPI (Swagger) Specification v2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) or [OpenAPI (Swagger) Specification v3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md).\n\nWe use [Swagger Client](https://github.com/swagger-api/swagger-js) and [Swagger Parser](https://github.com/APIDevTools/swagger-parser) internally.\n\n## Installation\n\nIn your application root directory, enter:\n\n```\n$ npm install loopback-connector-openapi --save\n```\n\nThis will install the module from npm and add it as a dependency to the application's `package.json` file.\n\n## Configuration\n\n### LoopBack 4 Usage\n\nTo interact with OpenAPI spec:\n\n1. Create a LoopBack 4 DataSource with OpenAPI connector using the `lb4 datasource` command.\n\n2. Create a service that maps to the operations using the `lb4 service` command.\n\n3. Create a controller that calls the service created in the above step using `lb4 controller` command.\n\nFor details, refer to the [Calling REST APIs documentation page](https://loopback.io/doc/en/lb4/Calling-rest-apis.html).\n\n### LoopBack 3 Usage\n\nTo interact with a Swagger API, configure a data source backed by the OpenAPI connector:\n\nWith code:\n\n```js\nvar ds = loopback.createDataSource('swagger', {\n  connector: 'loopback-connector-openapi',\n  spec: 'http://petstore.swagger.io/v2/swagger.json',\n});\n```\n\nWith JSON in `datasources.json` (for example, with basic authentication):\n\n```json\n\"SwaggerDS\": {\n    \"name\": \"SwaggerDS\",\n    \"connector\": \"swagger\",\n    \"spec\": \"http://petstore.swagger.io/v2/swagger.json\",\n    \"authorizations\": {\n      \"basic\": {\n        \"username\": \"your-username\",\n        \"password\": \"your-password\"\n      }\n    }\n}\n```\n\n## Data source properties\n\nSpecify the options for the data source with the following properties.\n\n| Property          | Description                                                                                                                                                                       | Default     |\n| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |\n| connector         | Must be `'loopback-connector-openapi'` to specify Swagger connector                                                                                                               | None        |\n| spec              | HTTP URL or path to the Swagger specification file (with file name extension `.yaml/.yml` or `.json`). File path must be relative to current working directory (`process.cwd()`). | None        |\n| validate          | When `true`, validates provided `spec` against Swagger specification 2.0 before initializing a data source.                                                                       | `false`     |\n| authorizations    | Security configuration for making authenticated requests to the API.                                                                                                              |             |\n| positional        | Use positional parameters instead of named parameters                                                                                                                             | `false`     |\n| forceOpenApi30    | Convert the Swagger 2.0 spec to OpenAPI 3.0                                                                                                                                       | `false`     |\n| mapToMethods      | map OpenAPI operations to method names                                                                                                                                            | `undefined` |\n| transformResponse | Transform the response object                                                                                                                                                     | `undefined` |\n\n### Mapping operations to methods\n\nBy default, the connector adds the following method names to the model:\n\n1. `x-operation-name` of the operation spec\n2. `operationId` of the operation spec\n3. The names from 1 and 2 with `\u003ctag\u003e_` prefix\n4. The camel case for all of the names above\n\nFor an operation with `{operationId: 'get_books', 'x-operation-name': 'getBooks'}`\nunder tag `BookController`, the following methods are added:\n\n- getBooks\n- get_books\n- BookController_getBooks\n- BookController_get_books\n- bookControllerGetBooks\n\nFor tagged interfaces, the connector adds the following method names to `apis.\u003ctag\u003e`:\n\n1. `x-operation-name` of the operation spec\n2. `operationId` of the operation spec\n3. The camel case for all of the names above\n\nFor an operation with `{operationId: 'get_books', 'x-operation-name': 'getBooks'}`\nunder tag `BookController`, the following methods are added:\n\n- getBooks\n- get_books\n\nA custom `mapToMethods` can be set on the connector to override the naming\nconventions. The signature of the method is as follows:\n\n```js\n/**\n * Get the method name for an operation\n * @param {string} tag - The tag. It will be '' for tagged interfaces.\n * @param {object} operationSpec - Operation spec\n * @param {string[]} existingNames - Optional array to track used names\n *\n * @returns A method name or an array of method names. Return undefined to\n * skip the operation.\n */\nfunction mapToMethods(tag, operationSpec, existingNames) {}\n```\n\nNow we can configure the connector to use our custom `mapToMethod`.\n\n```js\nvar ds = loopback.createDataSource('swagger', {\n  connector: 'loopback-connector-openapi',\n  spec: 'http://petstore.swagger.io/v2/swagger.json',\n  mapToMethods: mapToMethods,\n});\n```\n\n### Return value\n\nBy default, the methods return a `response` object with the following properties:\n\n```js\n{\n  url,\n  method,\n  status,\n  statusText,\n  headers, // See note below regarding headers\n  text,    // The textual content\n  body,    // The body object\n}\n```\n\nSee https://github.com/swagger-api/swagger-js#response-shape for more details.\n\nThe return value can be transformed by a custom `transformResponse` function\nconfigured for the connector:\n\n```js\nfunction transformResponse(res, operationSpec) {\n  if (res.status \u003c 400) {\n    return res.body;\n  }\n  const err = new Error(`${res.status} ${res.statusText}`);\n  err.details = res;\n  throw err;\n}\n```\n\nNow we can configure the connector to use our custom `transformResponse`.\n\n```js\nvar ds = loopback.createDataSource('swagger', {\n  connector: 'loopback-connector-openapi',\n  spec: 'http://petstore.swagger.io/v2/swagger.json',\n  transformResponse: transformResponse, // or transformResponse: true for a default transformer\n});\n```\n\n### Customize http/https client\n\nThe datasource configuration can override the `httpClient` or `httpClientOptions`:\n\n```js\n{\n  httpClientOptions: {\n  // See https://www.npmjs.com/package/node-fetch#options\n  agent: (url) =\u003e {\n    return url.protocol === 'http:'\n      ? new http.Agent({ timeout: 3000 })\n      : new https.Agent({ rejectUnauthorized: false });\n    },\n  },\n}\n```\n\nTo provide your own http client per\nhttps://github.com/swagger-api/swagger-js/blob/HEAD/docs/usage/http-client.md:\n\n```js\n{\n  httpClient: (request) =\u003e SwaggerClient.http(request),\n}\n```\n\n### Authentication\n\n#### Basic authentication\n\n```js\n{\n  authorizations: {\n    my_basic_auth: { username: 'foo', password: 'bar' },\n  }\n}\n```\n\n#### API Key\n\n```js\n{\n  authorizations: {\n    my_query_api_key_auth: 'my-api-key',\n    my_header_api_key_auth: 'my-api-key',\n  }\n}\n```\n\n#### OAuth2\n\n```js\n{\n  authorizations: {\n    my_oauth2_token: { token: { access_token: 'abcabc' } },\n  }\n}\n```\n\n**Note**: The key must correspond to a security scheme declared in the [Security Definitions object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object) within the `spec` document.\n\n### Creating a model from the Swagger data source\n\nThe Swagger connector loads the API specification document asynchronously. As a result, the data source won't be ready to create models until it is connected. For best results, use an event handler for the `connected` event of data source:\n\n```js\nds.once('connected', function(){\n  const PetService = ds.createModel('PetService', {});\n  ...\n});\n```\n\nOnce the model is created, all available Swagger API operations can be accessed as model methods, for example:\n\n```js\n...\nPetService.getPetById({petId: 1}, function (err, res){\n  ...\n});\n```\n\n#### How model methods are named for given Swagger API Operations:\n\nThis connector uses [swagger-client](https://github.com/swagger-api/swagger-js) which dominates the naming of generated methods for calling client API operations.\n\nFollowing is how it works:\n\n- When `operationId` is present, for example:\n\n```js\npaths: {\n  /weather/forecast:\n  get:\n    ...\n    operationId: weather.forecast\n    ...\n```\n\nHere, as `operationId` is present in Swagger specification, the generated method is named equivalent to `operationId`.\n\nNote:\nif `operationId` is of format equivalent to calling a nested function such as: `weather.forecast`, the resulting method name will replace `.` with `_` i.e. `weather.forecast` will result into `weather_forecast`.This means you can call `MyModel.weather_forecast()` to access this endpoint programmatically.\n\n- When `operationId` is not provided in Swagger specification, the method name is formatted as following:\n  `\u003coperationType (i.e. get, post, etc)\u003e + _ + \u003cpath parts separated by underscores\u003e`\n\nFor example:\n\n```\n/weather/forecast:\n  get:\n    ...\n```\n\nfor above operation, the resulting method name will be: `get_weather_forecast`.\n\nThis means you can call `MyModel.get_weather_forecast()` to access this endpoint programmatically.\n\n### Named parameters vs. positional parameters\n\nThe `positional` setting allows a method to be invoked with positional parameters based on the\nparameters/requestBody of the OpenAPI operation spec.\n\n```js\nconst result = await MyModel.my_operation(\n  // Parameters\n  '94555',\n  // Request body\n  {\n    verbose: true\n  },\n  // Additional options\n  {\n    requestContentType: 'application/json'\n  });\n});\n```\n\nWithout `positional` set to `true`, named parameters are expected:\n\n```js\nconst result = await MyModel.my_operation({\n  {\n    zipCode: '94555',\n  },\n  {\n    requestBody: {verbose: true},\n    requestContentType: 'application/json'\n  }\n});\n```\n\n### Extend a model to wrap/mediate API Operations\n\nOnce you define the model, you can wrap or mediate it to define new methods. The following example simplifies the `getPetById` operation to a method that takes `petID` and returns a Pet instance.\n\n```js\nPetService.searchPet = function (petID, cb) {\n  PetService.getPetById({ petId: petID }, function (err, res) {\n    if (err) cb(err, null);\n    var result = res.data;\n    cb(null, result);\n  });\n};\n```\n\nThis custom method on the `PetService` model can be exposed as REST API end-point. It uses `loopback.remoteMethod` to define the mappings:\n\n```js\nloopback.remoteMethod(PetService.searchPet, {\n  accepts: [\n    { arg: 'petID', type: 'string', required: true, http: { source: 'query' } },\n  ],\n  returns: { arg: 'result', type: 'object', root: true },\n  http: { verb: 'get', path: '/searchPet' },\n});\n```\n\n### Caching\n\nAs an experimental feature, loopback-connector-openapi is able to cache the result of `GET` requests.\n\n**Important: we support only one cache invalidation mechanism - expiration based on a static TTL value.**\n\nTo enable caching, you need to specify:\n\n- `cache.model` (required) - name of the model providing access to the cache.\n  The model should be extending loopback's built-in `KeyValueModel`\n  and be attached to one of key-value datasources (e.g. Redis or\n  eXtremeScale).\n\n- `cache.ttl` (required) - time to live for cache entries, the value\n  is in milliseconds. Note that certain cache implementations (notably\n  eXtremeScale) do not support sub-second precision for TTL.\n\n#### Example configuration\n\n`server/datasources.json`\n\n```json\n{\n  \"SwaggerDS\": {\n    \"connector\": \"swagger\",\n    \"cache\": {\n      \"model\": \"SwaggerCache\",\n      \"ttl\": 100\n    }\n  },\n  \"cache\": {\n    \"connector\": \"kv-redis\"\n  }\n}\n```\n\n`common/models/swagger-cache.json`\n\n```\n{\n  \"name\": \"SwaggerCache\",\n  \"base\": \"KeyValueModel\",\n  // etc.\n}\n```\n\n`server/model-config.json`\n\n```\n{\n  \"SwaggerCache\": {\n    \"dataSource\": \"cache\",\n    \"public\": false\n  }\n}\n```\n\n### Connector Hooks\n\nThe connector can be observed for `before execute` and `after execute` events. For example:\n\n```js\nconst ds = loopback.createDataSource('swagger', {\n    connector: 'loopback-connector-openapi',\n    spec: spec,\n    authorizations: authz || {},\n  });\n  ds.on('connected', function() {\n    ds.connector.observe('before execute', (ctx, next) =\u003e {\n      done(null, ctx.req);\n    });\n    ...\n  });\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopbackio%2Floopback-connector-openapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floopbackio%2Floopback-connector-openapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopbackio%2Floopback-connector-openapi/lists"}