{"_id":"@deli/crudl-base-connectors","_rev":"2-013b2d26068ebd3d800fbbe48de5c128","name":"@deli/crudl-base-connectors","description":"A connector layer to access any API uniformly using CRUD methods","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.2":{"name":"@deli/crudl-base-connectors","version":"0.1.2","description":"A connector layer to access any API uniformly using CRUD methods","main":"./lib/index.js","scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib","prepublish":"npm run test && npm run clean && npm run build","test":"jest"},"repository":{"type":"git","url":"git+https://github.com/crudlio/crudl-connectors-base.git"},"keywords":["admin","interface","api","crudl"],"author":{"name":"vonautomatisch"},"license":"MIT","bugs":{"url":"https://github.com/crudlio/crudl-connectors-base/issues"},"homepage":"http://crudl.io","files":["README.md","LICENSE","lib"],"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.2","babel-preset-es2015":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.2.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","jest":"^19.0.2","rimraf":"^2.6.1","sinon":"^2.1.0"},"dependencies":{"axios":"^0.16.1","path-to-regexp":"^1.7.0"},"gitHead":"454d541b3b3cf7eef5edf4fa84923458052c733a","_id":"@deli/crudl-base-connectors@0.1.2","_npmVersion":"5.6.0","_nodeVersion":"9.2.1","_npmUser":{"name":"okg","email":"george@oddcastles.com"},"maintainers":[{"name":"okg","email":"george@oddcastles.com"}],"dist":{"integrity":"sha512-gHxIIDHMjQ+LnUHsETULsFlk6oRmTffio3Kd/gngHkaS8i/TsLiRfOdoXmUZXeUG8rTNgsdQGIfI4xX28f0zAg==","shasum":"b62f29ddaed1975cee99777d442991d114258036","tarball":"https://registry.npmjs.org/@deli/crudl-base-connectors/-/crudl-base-connectors-0.1.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICg7CS2ZpTZ6SrNZ+e7DnRKXRKC+12z0LlQZzx/9xTaVAiEA1riER7CwMjVXA75TVaOlU+OjwUM2r7KwTlUbYojGC2M="}]},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/crudl-base-connectors-0.1.2.tgz_1513146052102_0.8855878582689911"},"deprecated":"this package has been deprecated"}},"readme":"A connector layer to access any API uniformly using CRUD methods.\n\n## Structure\n\nA connector is an object that provides crud methods (create, read, update, and delete). These methods accept requests and return promises, which in turn either resolve to responses or reject with an error. Because the crud methods return promises, they can be chained.\n\nThe simplest configuration of a connector is a backend-frontend pair. The backend connector translates the invoked methods and the passed requests into ajax calls. Using the frontend connector's `use` method, this basic pair can be extended with middleware.\n\n## Usage Examples\n\nUsing just the basic frontend-backend pair you can swiftly create a functioning connector:\n\n```js\nimport { createFrontendConnector, createBackendConnector } from '@crudlio/crudl-connectors-base';\n\nlet c = createFrontendConnector(createBackendConnector({ baseURL: 'localhost:3000/api/v1/' }));\nc.create({ url: '/users/', httpMethod: 'post', data: { firstName: 'Jane' }});\n```\n\nBy using middleware, you can customize your connectors and make them less verbose. For example the `crudToHttp` middleware maps the crud functions to the http methods, so that 'create' will result to 'post', 'read' to 'get', etc.\n\n```js\nconst mapping = { create: 'post', read: 'get', update: 'patch', delete: 'delete' };\nc = c.use(crudToHttp(mapping));\n\nc.update({ url: '/users/1', data: { lastName: 'Doe' } });\nc.read({ url: '/users/1/' }) // { id: 1, firstName: 'Jane', lastName: 'Doe' }\n```\n\nYou can bind connectors to specific endpoints using the `url` middleware. This middleware resolves the url pattern against the parameters passed to the connector.\n\n```js\nlet user = c.use(url('/users/:id'));\nlet blogEntry = c.use(url('/blogs/:blogId'));\n\nuser(1).read() // { id: 1, firstName: 'Jane', lastName: 'Doe' }\nblogEntry(12).read() // { id: 12, userId: 1, title: 'How to write middleware' }\n```\n\nPartial parametrization is also possible:\n\n```js\nlet detail = c.use(url('/:collection/:id'));\nlet user = detail('users') // The :collection is fixed to 'users' but :id is still open\nlet blogEntry = detail('blogs') // The :collection is fixed to 'blogs' but :id is still open\n\nuser(1).read()\nblogEntry(12).delete()\n```\n\n## Requests and Responses\n\nThe connectors achieve their task by transferring requests and responses between each other and amending them. The format of the request and response object is insofar open as connectors require only the `data` attribute to be present. Backend connectors may require more than that, and it's up to the application and the applied middleware to provide that.\n\nThe frontend connector's crud methods do not resolve to 'responses', instead they resolve to the response **data**. This is an important feature that makes the usage of connectors especially easy and intuitive. It keeps the response format transparent to the layers above connectors.\n\n\n## Middleware\n\nYou can extend the functionality of a connector with middleware:\n\n```js\nconst published = createFrontendConnector(createBackendConnector())\n  .use(url('localhost:3000/api/articles/'))\n  .use(transformData('read', data => data.filter(item => item.published)))\n\npublished.read().then((publishedArticles) => {\n  // ...\n});\n```\n\nMiddleware is a function that takes the next connector as its argument and returns a new connector. Consider the following middleware for transforming the response data:\n\n```js\nfunction transformData(methodRegExp, transform = data => data) {\n  const re = new RegExp(methodRegExp || '.*');\n\n  // The middleware function\n  return function transformDataMiddleware(next) {\n    // Checks if the call should be transformed. If yes, it applies the transform function\n    function checkAndTransform(method) {\n      return re.test(method)\n        ? req => next[method](req).then(res => Object.assign(res, { data: transform(res.data) }))\n        : req => next[method](req);\n    }\n\n    // The middleware connector:\n    return {\n      create: checkAndTransform('create'),\n      read: checkAndTransform('read'),\n      update: checkAndTransform('update'),\n      delete: checkAndTransform('delete'),\n    };\n  };\n}\n```\n\nNote that the middleware connectors do not need to implement all crud methods. If a middleware connector does not provide one of the crud methods, all pertinent requests will be automatically passed to the next connector in the chain.\n\nThe order of middleware matters. The last registered middleware is invoked first when making a request and last when processing a response. For example `c.use(mw1).use(mw2)` will result in the following chain/stack:\n```\nrequest   data     errors\n  ↓         ↑         ↑\n+-----------------------+\n|  FRONTEND CONNECTOR   |\n+-----------------------+\n  ↓         ↑         ↑         \nrequest  response  errors\n  ↓         ↑         ↑\n+-----------------------+\n|          MW2          |\n+-----------------------+\n  ↓         ↑         ↑         \nrequest  response  errors\n  ↓         ↑         ↑\n+-----------------------+\n|          MW1          |\n+-----------------------+\n  ↓         ↑         ↑         \nrequest  response  errors\n  ↓         ↑         ↑\n+-----------------------+\n|   BACKEND CONNECTOR   |\n+-----------------------+\n            ↕                  \n         ~~~~~~~           \n           API              \n         ~~~~~~~             \n```\n","maintainers":[{"name":"okg","email":"george@oddcastles.com"}],"time":{"modified":"2022-04-05T03:40:39.082Z","created":"2017-12-13T06:20:52.990Z","0.1.2":"2017-12-13T06:20:52.990Z"},"homepage":"http://crudl.io","keywords":["admin","interface","api","crudl"],"repository":{"type":"git","url":"git+https://github.com/crudlio/crudl-connectors-base.git"},"author":{"name":"vonautomatisch"},"bugs":{"url":"https://github.com/crudlio/crudl-connectors-base/issues"},"license":"MIT","readmeFilename":"README.md"}