This commit is contained in:
rijkvanzanten
2020-09-22 16:09:02 -04:00
parent 7caf429d1d
commit e703d1e928
2 changed files with 107 additions and 2 deletions

View File

@@ -1,3 +1,43 @@
# Creating a Custom API Endpoint
> TK
Custom endpoints are dynamically loaded from your configured extensions folder.
Custom endpoints are registered using a registration function:
```js
// extensions/endpoints/my-endpoint/index.js
module.exports = function registerEndpoint(router) {
router.get('/', (req, res) => res.send('Hello, World!'));
}
```
The `registerEndpoint` function receives two parameters: `router` and `context`. Router is an express Router
instance that's scoped to `/custom/<extension-name>`. `context` holds the following properties:
* `services` — All API interal services
* `exceptions` API exception objects that can be used to throw "proper" errors
* `database` — Knex instance that's connected to the current DB
* `env` Parsed environment variables
---
## Full example:
```js
// extensions/endpoints/recipes/index.js
module.exports = function registerEndpoint(router, { services, exceptions }) {
const { ItemsService } = services;
const { ServiceUnavailableException } = exceptions;
const recipeService = new ItemsService('recipes');
router.get('/', (req, res) => {
recipeService
.readByQuery({ sort: 'name', fields: '*' })
.then(results => res.json(results))
.catch(error => { throw new ServiceUnavailableException(error.message) });
});
}
```

View File

@@ -1,3 +1,68 @@
# Creating a Custom API Hook
> TK
Custom hooks are dynamically loaded from your configured extensions folder.
Custom hooks are registered using a registration function:
```js
// extensions/hooks/my-hook/index.js
module.exports = function registerHook() {
return {
'item.create.articles': function() {
axios.post('http://example.com/webhook');
}
}
}
```
Register function return an object with key = event, value = handler function.
The `registerHook` function receives one parameter: `context`. `context` holds the following properties:
* `services` — All API interal services
* `exceptions` API exception objects that can be used to throw "proper" errors
* `database` — Knex instance that's connected to the current DB
* `env` Parsed environment variables
Each handler function gets a `context` parameter with the following properties:
* `event` — Full event string
* `accountability` — Information about the current user
* `collection` — Collection that's being modified
* `item` Primary key(s) of the item(s) that's being modified
* `action` — Action that's performed
* `payload` Payload of the request
Events that are prefixed with `.before` run before the event is completed, and are blocking. These allow you to check / modify the payload before it's processed.
---
## Full example:
```js
// extensions/hooks/sync-with-external/index.js
module.exports = function registerHook({ services, exceptions }) {
const { ServiceUnavailableException, ForbiddenException } = exceptions;
return {
// Force everything to be admin only at all times
'item.*.*': async function({ item, accountability }) {
if (accountability.admin !== true) throw new ForbiddenException();
},
// Sync with external recipes service, cancel creation on failure
'item.recipes.create.before': async function(input) {
try {
await axios.post('https://example.com/recipes', input);
} catch (error) {
throw new ServiceUnavailableException(error);
}
input[0].syncedWithExample = true;
return input;
}
}
}
```