# Controllers

Controllers are JavaScript files that contain a set of methods, called actions, reached by the client according to the requested route. Whenever a client requests the route, the action performs the business logic code and sends back the response. Controllers represent the C in the model-view-controller (MVC) pattern. Just like all the other parts of the Strapi backend, controllers can be customized.

In most cases, the controllers will contain the bulk of a project's business logic. But as a controller's logic becomes more and more complicated, it's a good practice to use services to organize the code into re-usable parts.

# Implementation

Controllers can be generated or added manually, and the core controllers examples can help you get started creating custom ones.

# Adding a new controller

A new controller can be implemented:

  • with the interactive CLI command strapi generate
  • or manually by creating a JavaScript file:
    • in ./src/api/[api-name]/controllers/ for API controllers (this location matters as controllers are auto-loaded by Strapi from there)
    • or in a folder like ./src/plugins/[plugin-name]/controllers/ for , though they can be created elsewhere as long as the plugin interface is properly exported in the strapi-server.js file (see Server API for Plugins documentation)
// path: ./src/api/[api-name]/controllers/my-controller.js

module.exports = {
  async exampleAction(ctx, next) {
    try {
      ctx.body = 'ok';
    } catch (err) {
      ctx.body = err;
    }
  }
};

Each controller action can be an async or sync function. Every action receives a context object (ctx) as the first parameter. ctx contains the request context and the response context.

Example: GET /hello route calling a basic controller

A specific GET /hello route is defined, which takes hello.index as a handler. Every time a GET /hello request is sent to the server, Strapi calls the index action in the hello.js controller, which returns Hello World!:

// path: ./src/api/hello/routes/router.js

module.exports = {
  routes: [
    {
      method: 'GET',
      path: '/hello',
      handler: 'hello.index',
    }
  ]
}

// path: ./src/api/hello/controllers/hello.js

module.exports = {
  async index(ctx, next) { // called by GET /hello 
    ctx.body = 'Hello World!'; // we could also send a JSON
  },
};

✏️ NOTE

When a new content-type is created, Strapi builds a generic controller with placeholder code, ready to be customized.

# Extending core controllers

Default controllers are created for each content-type. These default controllers are used to return responses to API requests (e.g. when the GET /api/articles/3 is accessed, the findOne method of the default controller for the "Article" content-type is called). Default controllers can be customized to implement your own logic. The following code examples should help you get started.

✋ CAUTION

v4 controllers are currently being refactored. The code examples below will be updated soon to reflect these changes.

Collection type examples
Single type examples

# Usage

Controllers are declared and attached to a route. Controllers are automatically called when the route is called, so controllers usually do not need to be called explicitly. However, services can call controllers, and in this case the following syntax should be used:

// access an API controller
strapi.controller('api::api-name.controller-name');
// access a plugin controller
strapi.controller('plugin::plugin-name.service-name');