Strapi v4 - Extend core controller and create custom routes
Tags: javascript, beginners, programming, strapi
Published: 2022-03-16 22:36:54

## Contents
 - [Extend your controller in strapi v4](#extend-your-controller-in-strapi-v4) 
 - [Get Started](#get-started) 
 - [Customizing the api](#customizing-the-api) 
 - [Conclusion](#conclusion)

## Extend your controller in strapi v4

Hello everyone! I will be showing you how to extend your controllers and routes in strapi v4.

## Get Started

Let's create a project first of all. I think that if you want to customize the api, you probably know how to set up a strapi enviroment so I am going to skip this part.

```
// npm
npx create-strapi-app@latest my-project --quickstart

// yarn
yarn create strapi-app my-project --quickstart
```

Awesome after the initial setup we can quickly create a collection type called `Hello`, You can name this anything you want.

![Strapi 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrdstlno5787yq22y2su.png)
 
Now let's add a text field called `title`

![Strapi 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2dw54g5wfns78s8jd2kb.png)

![Strapi 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb29ix71ype0cw1i2j4m.png) 

Click finish, save your collection type and wait for the strapi app to restart. 

Now we should have the following collection type:

![Strapi 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9464xqr1kwtmfb2golst.png)

## Customizing the api

Alright let's get to work! Just kidding, it's really simple. follow the folder structure:

> **my-project > src > api > hello**

Here we have 4 folders available. 
- [content-types, controllers, routes, services]
Open up the javascript files inside the controllers and routes folders. They should both have the same name as your api. In my case `Hello.js`

Inside the **controllers > hello.js** replace the code with the following:

```
// src/api/hello/controllers/hello.js

"use strict";

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::hello.hello", ({ strapi }) => ({
  async findAll(ctx) {
    const entries = await strapi.db.query("api::hello.hello").findMany();

    ctx.body = entries;
  },
}));
```

Here we are extending the core controller to accept an extra function called findAll. Of course the core controller already has such a method called find. This is just for simplicity sake.

Now let's move to the **routes** folder and create a new file called custom-hello.js or something...

Inside we are going to define the routes: method, path and handler.

```
// src/api/hello/routes/custom-hello.js

module.exports = {
  routes: [
    {
      method: "GET",
      path: "/all-hellos",
      handler: "hello.findAll",
    },
  ],
};

```

And.. That's it! Now if we start our strapi app we can go to **settings > roles > public > hello*** and there we will see our new route!

![Strapi 05](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyqz7qsud0pr6q7wciv2.png)

Check findAll then save the changes. Create some entries inside the hellos collection and go to `http://localhost:1337/api/all-hellos` to view your collection! 🎉 

![Response api/hello](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qa46axmxxhpp54jffs4.png)

Nice! super easy eh?

## Conclusion

Customizing your api may seem like a hassle and in some cases unneccesary. But I think that everyone will, at one point run into an issue where something is simply not possible with the core api. 

For example, specifically updating the stock of a product by id without passing too many parameters.

```
// Addition to controlers/apiname.js

async updateStock(ctx) {
  const { id } = ctx.params;
  const { stock } = ctx.request.query;

  const entries = await strapi.db.query("api::product.product").update({
    where: { id },
    data: {
      stock,
    },
  });

  ctx.body = entries;
},
```
and for the routes
```
// Addition to the custom routes file

{
  method: "PUT",
  path: "/update-stock/:id",
  handler: "product.updateStock",
},
```

> Final PUT route `http://localhost:1337/api/update-stock/2?stock=5`

In this example I update the stock field of a product inside the product collection. Sometimes you want some extra control for specific tasks and extending the core controller / routes will help you with this.


Thank you for reading and Happy Coding 🥷‎‍💻