237 lines
4.5 KiB
Markdown
Raw Normal View History

# Services
2019-05-16 15:00:55 +02:00
See the [services concept](../concepts/concepts.md#services) for an overview.
2019-05-16 15:00:55 +02:00
## Core services
2019-05-16 15:00:55 +02:00
When you create a new Content type or a new model. You will see a new empty service has been created. It is because Strapi builds a generic service for your models by default and allows you to override and extend it in the generated files.
### Extending a Model Service
Here are the core methods (and their current implementation).
2019-05-24 14:42:53 +02:00
You can simply copy and paste this code to your own service file to customize the methods.
2019-05-16 15:00:55 +02:00
2019-06-14 23:28:08 +03:00
You can read about `strapi.query` calls [here](./queries.md)
2019-05-16 21:37:45 +02:00
2019-05-16 15:00:55 +02:00
::: warning
2019-05-24 14:42:53 +02:00
In the following example your controller, service and model is named `product`
2019-05-16 15:00:55 +02:00
:::
#### `find`
```js
module.exports = {
/**
* Promise to fetch all records
*
* @return {Promise}
*/
find(params, populate) {
return strapi.query(Product).find(params, populate);
},
};
```
#### `findOne`
```js
module.exports = {
/**
* Promise to fetch record
*
* @return {Promise}
*/
findOne(params, populate) {
return strapi.query(Product).findOne(params, populate);
},
};
```
#### `count`
```js
module.exports = {
/**
* Promise to count record
*
* @return {Promise}
*/
count(params) {
return strapi.query(Product).count(params);
},
};
```
#### `create`
```js
module.exports = {
/**
* Promise to add record
*
* @return {Promise}
*/
2019-08-12 16:58:18 +02:00
async create(data, { files } = {}) {
const entry = await strapi.query(model).create(data);
if (files) {
// automatically uploads the files based on the entry and the model
await this.uploadFiles(entry, files, { model });
return this.findOne({ id: entry.id });
}
return entry;
2019-05-16 15:00:55 +02:00
},
};
```
#### `update`
```js
module.exports = {
/**
* Promise to edit record
*
* @return {Promise}
*/
2019-08-12 16:58:18 +02:00
async update(params, data, { files } = {}) {
const entry = await strapi.query(model).update(params, data);
if (files) {
// automatically uploads the files based on the entry and the model
await this.uploadFiles(entry, files, { model });
return this.findOne({ id: entry.id });
}
return entry;
2019-05-16 15:00:55 +02:00
},
};
```
#### `delete`
```js
module.exports = {
/**
* Promise to delete a record
*
* @return {Promise}
*/
delete(params) {
return strapi.query(Product).delete(params);
},
};
```
#### `search`
```js
module.exports = {
/**
* Promise to search records
*
* @return {Promise}
*/
search(params) {
return strapi.query(Product).search(params);
},
};
```
#### `countSearch`
```js
module.exports = {
/**
* Promise to count searched records
*
* @return {Promise}
*/
countSearch(params) {
return strapi.query(Product).countSearch(params);
},
};
```
## Custom services
You can also create custom services to build your own business logic.
### How to create a custom service
There are two ways to create a service.
- Using the CLI `strapi generate:service product`. Read the [CLI documentation](../cli/CLI.md) for more information.
- Manually create a JavaScript file named in `./api/**/services/`.
#### Example
2019-05-24 14:42:53 +02:00
The goal of a service is to store reusable functions. An `email` service could be useful to send emails from different functions in our codebase:
**Path —** `./api/email/services/Email.js`.
2019-05-16 15:00:55 +02:00
```js
const nodemailer = require('nodemailer');
// Create reusable transporter object using SMTP transport.
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'user@gmail.com',
2019-05-16 15:00:55 +02:00
pass: 'password',
},
});
module.exports = {
2019-05-16 15:00:55 +02:00
send: (from, to, subject, text) => {
// Setup e-mail data.
const options = {
from,
to,
subject,
2019-05-16 15:00:55 +02:00
text,
};
// Return a promise of the function that sends the email.
return transporter.sendMail(options);
2019-05-16 15:00:55 +02:00
},
};
```
::: note
please make sure you installed `nodemailer` (`npm install nodemailer`) for this example.
:::
The service is now available through the `strapi.services` global variable. We can use it in another part of our codebase. For example a controller like below:
**Path —** `./api/user/controllers/User.js`.
2019-05-16 15:00:55 +02:00
```js
module.exports = {
// GET /hello
2019-05-16 15:00:55 +02:00
signup: async ctx => {
// Store the new user in database.
const user = await User.create(ctx.params);
// Send an email to validate his subscriptions.
2019-05-16 15:00:55 +02:00
strapi.services.email.send(
'welcome@mysite.com',
user.email,
'Welcome',
'...'
);
// Send response to the server.
ctx.send({
2019-05-16 15:00:55 +02:00
ok: true,
});
2019-05-16 15:00:55 +02:00
},
};
```