API Extensions
Services
When building extensions, you may use internal Directus services directly.
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 database schema, provided by the getSchema function. |
accountability | Accountability object, used for access control. Omission will use administrator permissions. null will use public permissions. |
This page uses endpoints to demonstrate how to use services, but they can also be used in other API extension types
ItemsService
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
const data = await itemsService.createOne({
title: 'Hello world!',
body: 'This is our first article',
});
Read an Item
const data = await itemsService.readOne('item_id');
Update an Item
const data = await itemsService.updateOne('item_id', {
title: "An updated title"
});
Delete an Item
const data = await itemsService.deleteOne('item_id');
CollectionsService
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
const data = await collectionsService.createOne({
name: 'articles',
meta: {
note: 'Blog posts.',
},
});
Read a Collection
const data = await collectionsService.readOne('collection_name');
Update a Collection
const data = await collectionsService.updateOne('collection_name', {
meta: {
note: 'Updated blog posts.',
},
});
Delete a Collection
const data = await collectionsService.deleteOne('collection_name');
See a complete list of all methods in the
CollectionsService
by looking at the Directus source code.FieldsService
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
await fieldsService.createField('collection_name', {
field: 'title',
type: 'string',
meta: {
icon: 'title',
},
schema: {
default_value: 'Hello World',
},
});
Read a Field
const data = await fieldsService.readOne('collection_name', 'field_name');
Update a Field
const data = await fieldsService.updateField('collection_name', 'field_name', {
meta: {
icon: 'title',
},
});
You cannot update the field name via Directus after creating the field.
Delete a Field
const data = await fieldsService.deleteField('collection_name', 'field_name');
RelationsService
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
const data = await relationsService.createOne({
collection: 'articles',
field: 'featured_image',
related_collection: 'directus_files',
});
Read a Relation
const data = await relationsService.readOne('collection_name', 'field_name');
Update a Relation
const data = await relationsService.updateOne(
'collection_name',
'field_name',
{
meta: {
one_field: 'articles',
},
},
);
Delete a Relation
const data = await relationsService.deleteOne('collection_name', 'field_name' );
FilesService
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
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:
import Busboy from 'busboy'
Then, inside of the route handler, pipe the request into Busboy:
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
const data = await filesService.readOne('file_id');
Update a File
const data = await filesService.updateOne('file_id', { title: 'Random' });
Delete a File
const data = await filesService.deleteOne('file_id');