Skip to content

Commit

Permalink
Services
Browse files Browse the repository at this point in the history
  • Loading branch information
phazonoverload committed Sep 19, 2024
1 parent 7f9f90f commit 167fcb3
Show file tree
Hide file tree
Showing 4 changed files with 318 additions and 6 deletions.
4 changes: 2 additions & 2 deletions content/10.extensions/3.api-extensions/2.endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The `index.js` or `index.ts` file exports a register function that is read by Di
### Entrypoint Example

```js
export default (router) => {
export default (router, context) => {
router.get('/', (req, res) => res.send('Hello, World!'));
};
```
Expand All @@ -25,7 +25,7 @@ Alternatively, you can export a configuration object to be able to customize the
```js
export default {
id: 'greet',
handler: (router) => {
handler: (router, countext) => {
router.get('/', (req, res) => res.send('Hello, World!'));
router.get('/intro', (req, res) => res.send('Nice to meet you.'));
router.get('/goodbye', (req, res) => res.send('Goodbye!'));
Expand Down
314 changes: 313 additions & 1 deletion content/10.extensions/3.api-extensions/4.services.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,317 @@
---
description:
description: When building extensions, you may use internal Directus services directly.
---

# Services

API extensions can directly use internal Directus services like the `ItemsService`, `CollectionsService`, `FilesService`, and more, accessible through the `context` parameter.

When initializing services, you will need the following:

| Parameter | Description |
| --- | --- |
| `schema` | [Knex](https://knexjs.org/) database schema, provided by the `getSchema` function. |
| `accountability` | Accountability object, used for access control. Omission will use administrator permissions. `null` will use public permissions. |

::callout{type="link" url="https://github.com/directus/directus/tree/main/api/src/services"}
See a complete list of all services available by looking at the Directus source code.
::

This page uses endpoints to demonstrate how to use services, but they can also be used in other API extension types

## `ItemsService`

```js
export default (router, context) => {
const { services, getSchema } = context;
const { ItemsService } = services;

router.get('/', async (req, res) => {
const itemsService = new ItemsService('collection_name', {
schema: await getSchema(),
accountability: req.accountability
});

// Your route handler logic
});
};
```

### Create an Item

```js
const data = await itemsService.createOne({
title: 'Hello world!',
body: 'This is our first article',
});
```

### Read an Item

```js
const data = await itemsService.readOne('item_id');
```

### Update an Item

```js
const data = await itemsService.updateOne('item_id', {
title: "An updated title"
});
```

### Delete an Item

```js
const data = await itemsService.deleteOne('item_id');
```

::callout{type="link" url="https://github.com/directus/directus/blob/main/api/src/services/items.ts"}
See a complete list of all methods in the `ItemsService` by looking at the Directus source code.
::

## `CollectionsService`

```js
export default (router, context) => {
const { services, getSchema } = context;
const { CollectionsService } = services;

router.get('/', async (req, res) => {
const collectionsService = new CollectionsService({
schema: await getSchema(),
accountability: req.accountability
});

// Your route handler logic
});
};
```

### Create a Collection

```js
const data = await collectionsService.createOne({
name: 'articles',
meta: {
note: 'Blog posts.',
},
});
```

### Read a Collection

```js
const data = await collectionsService.readOne('collection_name');
```

### Update a Collection

```js
const data = await collectionsService.updateOne('collection_name', {
meta: {
note: 'Updated blog posts.',
},
});
```

### Delete a Collection

```js
const data = await collectionsService.deleteOne('collection_name');
```

::callout{type="link" url="https://github.com/directus/directus/blob/main/api/src/services/collections.ts"}
See a complete list of all methods in the `CollectionsService` by looking at the Directus source code.
::

## `FieldsService`

```js
export default (router, context) => {
const { services, getSchema } = context;
const { FieldsService } = services;

router.get('/', async (req, res) => {
const fieldsService = new FieldsService({
schema: await getSchema(),
accountability: req.accountability
});

// Your route handler logic
});
}
```

### Create a Field

```js
await fieldsService.createField('collection_name', {
field: 'title',
type: 'string',
meta: {
icon: 'title',
},
schema: {
default_value: 'Hello World',
},
});
```

### Read a Field

```js
const data = await fieldsService.readOne('collection_name', 'field_name');
```

### Update a Field

```js
const data = await fieldsService.updateField('collection_name', 'field_name', {
meta: {
icon: 'title',
},
});
```

::callout{type="info"}
You cannot update the field name via Directus after creation.
::

### Delete a Field

```js
const data = await fieldsService.deleteField('collection_name', 'field_name');
```

## `RelationsService`

```js
export default (router, context) => {
const { services, getSchema } = context;
const { RelationsService } = services;

router.get('/', async (req, res) => {
const relationsService = new RelationsService({
schema: await getSchema(),
accountability: req.accountability
});

// Your route handler logic
});
};
```

### Create a Relation

```js
const data = await relationsService.createOne({
collection: 'articles',
field: 'featured_image',
related_collection: 'directus_files',
});
```

### Read a Relation

```js
const data = await relationsService.readOne('collection_name', 'field_name');
```

### Update a Relation

```js
const data = await relationsService.updateOne(
'collection_name',
'field_name',
{
meta: {
one_field: 'articles',
},
},
);
```

### Delete a Relation

```js
const data = await relationsService.deleteOne('collection_name', 'field_name' );
```

::callout{type="link" url="https://github.com/directus/directus/blob/main/api/src/services/relations.ts"}
See a complete list of all methods in the `RelationsService` by looking at the Directus source code.
::

## `FilesService`

```js
export default (router, context) => {
const { services, getSchema } = context;
const { FilesService } = services;

router.get('/', async (req, res) => {
const filesService = new FilesService({
schema: await getSchema(),
accountability: req.accountability
});

// Your route handler logic
});
};
```

### Import a File

```js
const assetKey = await filesService.importOne({
url: file_url,
data: file_object,
});
```

### Upload a File

Uploading a file requires the use of an external dependency called _Busboy_, a streaming parser for Node.js. Import it at the top of your extension:

```js
import Busboy from 'busboy'
```

Then, inside of the route handler, pipe the request into Busboy:

```js
const busboy = Busboy({ headers: req.headers });

busboy.on('file', async (_, fileStream, { filename, mimeType }) => {
const primaryKey = await filesService.uploadOne(fileStream, {
filename_download: filename,
type: mimeType,
storage: 'local',
});
});

req.pipe(busboy);
```

### Read a File

```js
const data = await filesService.readOne('file_id');
```

### Update a File

```js
const data = await filesService.updateOne('file_id', { title: 'Random' });
```

### Delete a File

```js
const data = await filesService.deleteOne('file_id');
```

::callout{type="link" url="https://github.com/directus/directus/blob/main/api/src/services/files.ts"}
See a complete list of all methods in the `FilesService` by looking at the Directus source code.
::

4 changes: 2 additions & 2 deletions content/10.extensions/4.app-extensions/7.ui-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ For example, to adjust the text color of a button on hover:

::callout{type="info" title="Explore Component CSS Variables"}

Refer to the full list of component based CSS variables [in our codebase](https://github.com/directus/directus/tree/main/app/src/components).
Refer to the full list of component based CSS variables [in our source code](https://github.com/directus/directus/tree/main/app/src/components).

::

Expand All @@ -56,7 +56,7 @@ Examples of CSS variables include `--border-normal`, `--foreground-normal` `-pur

::callout{type="info" title="Explore Light and Dark Theme CSS Variables"}

Refer to our [codebase](https://github.com/directus/directus/tree/main/app/src/styles/themes) for a full list of CSS
Refer to our [source code](https://github.com/directus/directus/tree/main/app/src/styles/themes) for a full list of CSS
variables.

::
2 changes: 1 addition & 1 deletion content/10.extensions/4.app-extensions/8.composables.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,4 @@ const data = totalCount.value; // read the total item count
## Next Steps

While these core composables cover many common use cases, for a complete reference of all available Extension SDK
composables within Directus, check out our [codebase](https://github.com/directus/directus/blob/main/app/src/composables/use-system.ts). Our codebase also contains the [full list in of stores](https://github.com/directus/directus/blob/main/app/src/composables/use-system.ts).
composables within Directus, check out our [source code](https://github.com/directus/directus/blob/main/app/src/composables/use-system.ts). Our source code also contains the [full list in of stores](https://github.com/directus/directus/blob/main/app/src/composables/use-system.ts).

0 comments on commit 167fcb3

Please sign in to comment.