How create custom controller?

Hey! I am developing my plugin. It has two tasks: 1. Requesting data from another place by calling the controller through the API (let’s call it point A). 2. Adding this data to the content-type collection (let’s call it point B). It turns out that I have two controllers, one responsible for point A, and the other for point B. How best could I implement this task?

System Information
  • Strapi Version:
  • Operating System:
  • Database:
  • Node Version:
  • NPM Version:
  • Yarn Version:

Controllers are usually attached to an endpoint, is your goal to do all of this in one REST call or are you intentionally wanting to make 2 REST calls?

If the former is true, then you want one controller and you can build out two services that can be called in that controller (or skip the services and write it all into one controller).

For simplicity’s sake, I’m ready to do everything in one controller. It’s just that I don’t quite understand how I can access CREATE to my collection of types created inside the plugin. I’m not sure I’m doing everything right, could you give me a hint?

In short, when making a request for “/ test”, I want to add data from the body to the collection of types, and make a request for a third-party api, upon whose response, change the newly created data

So yes that could be done in one controller, the best way to view how controllers work is to review how normal auto-generated models functions (or maybe looking at some of our other plugins).

I would suggest reviewing these 3 documents first:

Now functionally speaking your, lets say single controller, would work is your plugin frontend code in the admin makes a request to this controller passing along the request body and your admin JWT (in an authorization header). Given I am making the assumption that this request is happening for the admin, it doesn’t have to.

The logic of your controller would be to accept the incoming body on ctx.request.body and do something with it. Now depending on your use-case I would suggest making the async call to the external resource first and then use the strapi.query('your-collection-type').create({ yourDataHere}) instead of the syntax you provided.

However you could do the strapi.query('your-collection-type').create({ yourDataHere}) first, then do a strapi.query('your-collection-type').update({ id: theIDYouCreated }, {yourUpdatedDataHere }) also but it’s not as efficient since you are making 2 calls to the database instead of one.

In this case you are skipping the services entirely, but you could abstract out those direct queries to services that could be reused elsewhere, but the same is not true for controllers, generally speaking every endpoint/route/handler (these are used interchangeably but they mean the same thing) should always have their own controller.

Controllers (Koa calls them handler functions) are specific to Koa.js itself, they are the logic that koa runs when a route is called. Services are something we added to Strapi to create reusable functions that could be pulled in and used by multiple controllers, and queries are just that the Internal API abstraction layer between the Strapi framework and the Database ORM used to translate them to a database query (SQL or NoSQL syntax).

Hopefully that makes a little more sense.

1 Like