Back to Directus

Services

content/guides/09.extensions/2.api-extensions/4.services.md

latest6.9 KB
Original Source

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:

ParameterDescription
schemaThe database schema, provided by the getSchema function.
accountabilityAccountability object, used for access control. Omission or null will use administrator permissions.

::callout{icon="material-symbols:link" to="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.

::callout{icon="material-symbols:warning-rounded" color="warning"} Infinite Recursion If you are listening to an event and your handler is emitting the same event, you will need to pass { emitEvents: false } in order to prevent infinite recursion. ::

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{icon="material-symbols:link" to="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{icon="material-symbols:link" to="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:  'field_name',
	meta: {
		icon: 'title',
	},
});

::callout{icon="material-symbols:info-outline"} You cannot update the field name via Directus after creating the field. ::

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{icon="material-symbols:link" to="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(file_url, 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{icon="material-symbols:link" to="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. ::