 4c4a4c1dd3
			
		
	
	
		4c4a4c1dd3
		
			
		
	
	
	
	
		
			
			* docs: improve getting started Signed-off-by: Jim LAURIE <j.laurie6993@gmail.com> * docs: review quickstart video and some steps Signed-off-by: Jim LAURIE <j.laurie6993@gmail.com> * docs: review concepts Signed-off-by: Jim LAURIE <j.laurie6993@gmail.com> * docs: review email - upload plugins Signed-off-by: Jim LAURIE <j.laurie6993@gmail.com> * fix: PR feedback Signed-off-by: Jim LAURIE <j.laurie6993@gmail.com> * fix: PR feedback type conflict Signed-off-by: Jim LAURIE <j.laurie6993@gmail.com>
		
			
				
	
	
	
		
			7.3 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Controllers
Concept
Controllers are JavaScript files which contain a set of methods called actions reached by the client according to the requested route. It means that every time a client requests the route, the action performs the business logic coded and sends back the response. They represent the C in the MVC pattern. In most cases, the controllers will contain the bulk of a project's business logic.
module.exports = {
  // GET /hello
  index: async ctx => {
    return 'Hello World!';
  },
};
In this example, any time a web browser is pointed to the /hello URL on your app, the page will display the text: Hello World!.
Where are the controllers defined?
The controllers are defined in each ./api/**/controllers/ folder. Every JavaScript file put in these folders will be loaded as a controller. They are also available through the strapi.controllers and strapi.api.**.controllers global variables.
Core controllers
When you create a new Content Type you will see a new empty controller has been created. This is because Strapi builds a generic controller for your models by default and allows you to override and extend it in the generated files.
Extending a Model Controller
Here are the core methods (and their current implementation). You can simply copy and paste this code in your own controller file to customize the methods.
::: warning
In the following example we will assume your controller, service and model are named restaurant
:::
Utils
First require the utility functions
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
- parseMultipartData: This function parses Strapi's formData format.
- sanitizeEntity: This function removes all private fields from the model and its relations.
Collection Type
:::: tabs
::: tab find
find
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Retrieve records.
   *
   * @return {Array}
   */
  async find(ctx) {
    let entities;
    if (ctx.query._q) {
      entities = await strapi.services.restaurant.search(ctx.query);
    } else {
      entities = await strapi.services.restaurant.find(ctx.query);
    }
    return entities.map(entity => sanitizeEntity(entity, { model: strapi.models.restaurant }));
  },
};
:::
::: tab findOne
findOne
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Retrieve a record.
   *
   * @return {Object}
   */
  async findOne(ctx) {
    const { id } = ctx.params;
    const entity = await strapi.services.restaurant.findOne({ id });
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::: tab count
count
module.exports = {
  /**
   * Count records.
   *
   * @return {Number}
   */
  count(ctx) {
    if (ctx.query._q) {
      return strapi.services.restaurant.countSearch(ctx.query);
    }
    return strapi.services.restaurant.count(ctx.query);
  },
};
:::
::: tab create
create
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Create a record.
   *
   * @return {Object}
   */
  async create(ctx) {
    let entity;
    if (ctx.is('multipart')) {
      const { data, files } = parseMultipartData(ctx);
      entity = await strapi.services.restaurant.create(data, { files });
    } else {
      entity = await strapi.services.restaurant.create(ctx.request.body);
    }
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::: tab update
update
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Update a record.
   *
   * @return {Object}
   */
  async update(ctx) {
    const { id } = ctx.params;
    let entity;
    if (ctx.is('multipart')) {
      const { data, files } = parseMultipartData(ctx);
      entity = await strapi.services.restaurant.update({ id }, data, {
        files,
      });
    } else {
      entity = await strapi.services.restaurant.update({ id }, ctx.request.body);
    }
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::: tab delete
delete
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Delete a record.
   *
   * @return {Object}
   */
  async delete(ctx) {
    const { id } = ctx.params;
    const entity = await strapi.services.restaurant.delete({ id });
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::::
Single Type
:::: tabs
::: tab find
find
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Retrieve the record.
   *
   * @return {Array}
   */
  async find(ctx) {
    const entity = await strapi.services.restaurant.findOne();
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::: tab update
update
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Update the record.
   *
   * @return {Object}
   */
  async update(ctx) {
    let entity;
    if (ctx.is('multipart')) {
      const { data, files } = parseMultipartData(ctx);
      entity = await strapi.services.restaurant.createOrUpdate(data, {
        files,
      });
    } else {
      entity = await strapi.services.restaurant.createOrUpdate(ctx.request.body);
    }
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::: tab delete
delete
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
  /**
   * Delete the record.
   *
   * @return {Object}
   */
  async delete(ctx) {
    const entity = await strapi.services.restaurant.delete();
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  },
};
:::
::::
Custom controllers
You can also create custom controllers to build your own business logic and API endpoints.
How to create a custom controller
There are two ways to create a controller:
- Using the CLI strapi generate:controller restaurant.
 Read the CLI documentation for more information.
- Manually create a JavaScript file in ./api/**/controllers.
Adding Endpoints
Each controller’s action must be an async function.
Every action receives a context (ctx) object as first parameter containing the request context and the response context.
Example
In this example, we are defining a specific route in ./api/hello/config/routes.json that takes Hello.index as handler.
It means that every time a request GET /hello is sent to the server, Strapi will call the index action in the Hello.js controller.
Our index action will return Hello World!. You can also return a JSON object.
Path — ./api/hello/config/routes.json.
{
  "routes": [
    {
      "method": "GET",
      "path": "/hello",
      "handler": "Hello.index"
    }
  ]
}
Path — ./api/hello/controllers/Hello.js.
module.exports = {
  // GET /hello
  index: async ctx => {
    ctx.send('Hello World!');
  },
};
::: tip
A route handler can only access the controllers defined in the ./api/**/controllers folders.
:::