{"id":19165730,"url":"https://github.com/loopbackio/loopback-connector-rest","last_synced_at":"2025-05-15T17:01:45.189Z","repository":{"id":8816771,"uuid":"10515010","full_name":"loopbackio/loopback-connector-rest","owner":"loopbackio","description":"Connect Loopback to a REST API","archived":false,"fork":false,"pushed_at":"2024-10-17T16:21:06.000Z","size":593,"stargazers_count":75,"open_issues_count":7,"forks_count":82,"subscribers_count":60,"default_branch":"master","last_synced_at":"2024-12-16T20:32:07.495Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://loopback.io/doc/en/lb2/REST-connector.html","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","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}},"created_at":"2013-06-05T23:30:39.000Z","updated_at":"2024-10-17T16:21:10.000Z","dependencies_parsed_at":"2023-11-16T04:30:58.851Z","dependency_job_id":"b2b75393-ec67-430e-9839-f3cdf404c1dc","html_url":"https://github.com/loopbackio/loopback-connector-rest","commit_stats":{"total_commits":248,"total_committers":45,"mean_commits":5.511111111111111,"dds":0.5362903225806452,"last_synced_commit":"2bfb39fa1eed86cce4fdc550ad5d8443d604e013"},"previous_names":["strongloop/loopback-connector-rest"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-rest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-rest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-rest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopbackio%2Floopback-connector-rest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loopbackio","download_url":"https://codeload.github.com/loopbackio/loopback-connector-rest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247737788,"owners_count":20987721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-09T09:29:08.853Z","updated_at":"2025-04-07T22:07:37.151Z","avatar_url":"https://github.com/loopbackio.png","language":"JavaScript","readme":"# loopback-connector-rest\n\n## Overview\n\nThe LoopBack REST connector enables applications to interact with other (third party) REST APIs using a template-driven approach.\nIt supports two different styles of API invocations:\n\n- [Resource operations](#resource-operations)\n- [Defining a custom method using a template](#defining-a-custom-method-using-a-template)\n\n## Installation\n\nIn your application root directory, enter:\n\n```shell\n$ npm install loopback-connector-rest --save\n```\n\nThis will install the module from npm and add it as a dependency to the application's [package.json](http://loopback.io/doc/en/lb3/package.json.html) file.\n\n## Creating a REST data source\n\nUse the [data source generator](http://loopback.io/doc/en/lb3/Data-source-generator) to add a REST data source to your application.\n\nFor LoopBack 2.x:\n\n```shell\n$ apic create --type datasource\n```\n\nFor LoopBack 2.x or 3.0:\n\n```shell\n$ lb datasource\n```\n\nWhen prompted, scroll down in the list of connectors and choose **REST services (supported by StrongLoop)**.\nThis adds an entry to [datasources.json](http://loopback.io/doc/en/lb3/datasources.json.html), for example:\n\n```javascript\n...\n  \"myRESTdatasource\": {\n    \"name\": \"myRESTdatasource\",\n    \"connector\": \"rest\"\n  }\n...\n```\n\n## LoopBack 4 Usage\n\n1. Create a LoopBack 4 DataSource with REST 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## Configuring a REST data source\n\nConfigure the REST connector by editing `datasources.json` manually (for example using the Google Maps API):\n\n**/server/datasources.json**\n\n```javascript\n...\n\"geoRest\": {\n  \"connector\": \"rest\",\n  \"debug\": \"false\",\n  \"operations\": [{\n    \"template\": {\n      \"method\": \"GET\",\n      \"url\": \"http://maps.googleapis.com/maps/api/geocode/{format=json}\",\n      \"headers\": {\n        \"accepts\": \"application/json\",\n        \"content-type\": \"application/json\"\n      },\n      \"query\": {\n        \"address\": \"{street},{city},{zipcode}\",\n        \"sensor\": \"{sensor=false}\"\n      },\n      \"responsePath\": \"$.results[0].geometry.location\"\n    },\n    \"functions\": {\n      \"geocode\": [\"street\", \"city\", \"zipcode\"]\n    }\n  }]\n}\n...\n```\n\nThe `operations` property is an array of objects, each of which can have these properties:\n\n- `template`: An object that defines a custom method using a template; see [Defining a custom method using a template](#defining-a-custom-method-using-a-template).\n- `functions`: An object that maps a JavaScript function to a list of parameter names.\n\nThe example above creates a function `geocode(street, city, zipcode)` whose first argument is `street`, second is `city`, and third is `zipcode`.  LoopBack application code can call the function anywhere; for example, in a boot script, via middleware, or within a model's JavaScript file if attached to the REST datasource.\n\n## Configure options for request\n\nThe REST connector uses the [request](https://www.npmjs.com/package/request) module as the HTTP client.\nYou can configure the same options as for the `request()` function.\nSee [`request(options, callback)`](https://www.npmjs.com/package/request#request-options-callback).\n\nYou can configure options `options` property at two levels:\n\n- Data source level (common to all operations)\n- Operation level (specific to the declaring operation)\n\nThe following example sets `Accept` and `Content-Type` to `\"application/json\"` for all requests.\nIt also sets `strictSSL` to false so the connector allows self-signed SSL certificates.\n\n**/server/datasources.json**\n\n```javascript\n{\n  \"connector\": \"rest\",\n  \"debug\": false,\n  \"options\": {\n    \"headers\": {\n      \"accept\": \"application/json\",\n      \"content-type\": \"application/json\"\n    },\n    \"strictSSL\": false\n  },\n  \"operations\": [\n    {\n      \"template\": {\n        \"method\": \"GET\",\n        \"url\": \"http://maps.googleapis.com/maps/api/geocode/{format=json}\",\n        \"query\": {\n          \"address\": \"{street},{city},{zipcode}\",\n          \"sensor\": \"{sensor=false}\"\n        },\n        \"options\": {\n          \"strictSSL\": true,\n          \"useQuerystring\": true\n        },\n        \"responsePath\": \"$.results[0].geometry.location\"\n      },\n      \"functions\": {\n        \"geocode\": [\"street\", \"city\", \"zipcode\"]\n      }\n    }\n  ]\n}\n```\n\n### Resource operations\n\nIf the REST API supports create, read, update, and delete (CRUD) operations for resources,\nyou can simply bind the model to a REST endpoint that follows REST conventions.\n\nFor example, the following methods would be mixed into your model class:\n\n- create: `POST /users`\n- findById: `GET /users/:id`\n- delete: `DELETE /users/:id`\n- update: `PUT /users/:id`\n- find: `GET /users?limit=5\u0026username=ray\u0026order=email`\n\nFor example:\n\n**/server/boot/script.js**\n\n```javascript\nmodule.exports = function (app) {\n  var ds = app.loopback.createDataSource({\n    connector: require(\"loopback-connector-rest\"),\n    debug: false,\n    baseURL: \"http://localhost:3000\",\n  });\n\n  var User = ds.createModel(\"user\", {\n    name: String,\n    bio: String,\n    approved: Boolean,\n    joinedAt: Date,\n    age: Number,\n  });\n\n  User.create(\n    new User({\n      name: \"Mary\",\n    }),\n    function (err, user) {\n      console.log(user);\n    }\n  );\n\n  User.find(function (err, user) {\n    console.log(user);\n  });\n\n  User.findById(1, function (err, user) {\n    console.log(err, user);\n  });\n\n  User.update(\n    new User({\n      id: 1,\n      name: \"Raymond\",\n    }),\n    function (err, user) {\n      console.log(err, user);\n    }\n  );\n};\n```\n\n### Setting the resource URL\n\nYou can set the remote URL when using create, read, update, or delete functionality by setting the `resourceName` property on a model definition.\nThis allows for a local model name that is different from the remote resource name.\n\nFor example:\n\n```javascript\nvar config = {\n  name: \"ServiceTransaction\",\n  base: \"PersistedModel\",\n  resourceName: \"transactions\",\n};\n\nvar ServiceTransaction = ds.createModel(\"ServiceTransaction\", {}, config);\n```\n\nNow there will be a resource model named `ServiceTransaction`, but whose URLs call out to `baseUrl - '/transactions'`\n\nWithout setting `resourceName` the calls would have been made to `baseUrl - '/ServiceTransaction'`.\n\n## Defining a custom method using a template\n\nThe `template` object specifies the REST API invocation as a JSON template, with the following properties:\n\n| Property       | Description                                                                                                                                  | Type                                             |\n| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |\n| `method`       | HTTP method                                                                                                                                  | String (one of \"GET\", \"POST\", \"PUT\", and so on). |\n| `url`          | The URL of the request                                                                                                                       | String; template values allowed.                 |\n| `headers`      | HTTP headers                                                                                                                                 | Object                                           |\n| `query`        | Query strings                                                                                                                                | Object; template values allowed.                 |\n| `responsePath` | Optional JSONPath applied to the HTTP body. See [https://github.com/s3u/JSONPath](https://github.com/s3u/JSONPath) for syntax of JSON paths. | String                                           |\n| `fullResponse` | Optional flag to return full response, rather than just body.                                                                                | Boolean                                          |\n\nThe template variable syntax is:\n\n`{name=defaultValue:type}`\n\nTo specify that the variable value is required, add the prefix `!` or `^`.\n\nFor example:\n\n```javascript\ntemplate: {\n    \"method\": \"GET\",\n    \"url\": \"http://maps.googleapis.com/maps/api/geocode/{format=json}\",\n    \"headers\": {\n      \"accepts\": \"application/json\",\n      \"content-type\": \"application/json\"\n    },\n    \"query\": {\n      \"address\": \"{street},{city},{zipcode}\",\n      \"sensor\": \"{sensor=false}\"\n    },\n    \"responsePath\": \"$.results[0].geometry.location\"\n  }\n```\n\nThe following table provides several examples:\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003eVariable definition\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e'{x=100:number}'\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eDefine a variable x of number type and default value 100.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e'{x:number}'\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eDefine a variable x of number type\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e'{x}'\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eDefine a variable x\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e'{x=100}ABC{y}123'\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\n        \u003cp\u003eDefine two variables x and y. The default value of x is 100. The resolved value will be a concatenation of x, 'ABC', y, and '123'. For example, x=50, y=YYY will produce '50ABCYYY123'\u003c/p\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e'{!x}'\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eDefine a required variable x\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e'{x=100}ABC{^y}123'\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eDefine two variables, x and y. The default value of x is 100, and y is required.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nTo use custom methods, configure the REST connector with the `operations` property, which is an array of objects, each of which can have these properties:\n\n- `template` defines the API structure.\n- `functions` defines JavaScript methods that accept the specified list of parameter names.\n\n```javascript\nvar loopback = require(\"loopback\");\n\nvar ds = loopback.createDataSource({\n  connector: require(\"loopback-connector-rest\"),\n  debug: false,\n  operations: [\n    {\n      template: {\n        method: \"GET\",\n        url: \"http://maps.googleapis.com/maps/api/geocode/{format=json}\",\n        headers: {\n          accepts: \"application/json\",\n          \"content-type\": \"application/json\",\n        },\n        query: {\n          address: \"{street},{city},{zipcode}\",\n          sensor: \"{sensor=false}\",\n        },\n        responsePath: \"$.results[0].geometry.location\",\n      },\n      functions: {\n        geocode: [\"street\", \"city\", \"zipcode\"],\n      },\n    },\n  ],\n});\n```\n\nNow you can invoke the geocode API in Node.js as follows:\n\n```javascript\nModel.geocode(\"107 S B St\", \"San Mateo\", \"94401\", processResponse);\n```\n\nBy default, the REST connector also provides an 'invoke' method to call the REST API with an object of parameters, for example:\n\n```javascript\nModel.invoke(\n  { street: \"107 S B St\", city: \"San Mateo\", zipcode: \"94401\" },\n  processResponse\n);\n```\n\n## Parameter/variable mapping to HTTP (since 2.0.0)\n\nNOTE: This feature is available with `loopback-connector-rest` version 2.0.0 and later.\n\nBy default, variables in the template are mapped to HTTP sources based on their root property.\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003eRoot property\u003c/th\u003e\n      \u003cth\u003eHTTP source\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eurl\u003c/td\u003e\n      \u003ctd\u003epath\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003equery\u003c/td\u003e\n      \u003ctd\u003equery\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003ebody\u003c/td\u003e\n      \u003ctd\u003ebody\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eheaders\u003c/td\u003e\n      \u003ctd\u003eheader\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nYou can further customize the source in the parameter array of the function mapping, for example:\n\n```javascript\n{\n  \"template\": {\n    \"method\": \"POST\",\n    \"url\": \"http://localhost:3000/{p}\",\n    \"headers\": {\n      \"accept\": \"application/{format}\"\n    },\n    \"query\": {\n      \"x\": \"{x}\",\n      \"y\": 2\n    },\n    \"body\": {\n      \"a\": \"{a:number}\",\n      \"b\": \"{b=true}\"\n    }\n  },\n  \"functions\": {\n    \"myOp\": [\n      \"p\",\n      \"x\",\n      \"a\",\n      {\n        \"name\": \"b\",\n        \"source\": \"header\"\n      }\n    ]\n  }\n}\n```\n\nFor the template above, the variables will be mapped as follows:\n\n- p - path\n- x - query\n- a - body\n- b - header\n\nPlease note that path variables are appended to the path, for example, `/myOp/:p.`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopbackio%2Floopback-connector-rest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floopbackio%2Floopback-connector-rest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopbackio%2Floopback-connector-rest/lists"}