Supporting modular programming (via plugin system)

From : https://github.com/strapi/strapi/discussions/7808
(Edited)

Firstly, I’m a big fan of strapi. (Strapi Team is doing great job👍 )

As the system grows bigger, I had to organize apis into groups.

So I tried to solve it by using local plugin. But I realized that the two commands below works differently.

strapi generate:api Test // This creates REST API and GraphQL queries automatically
strapi generate:api Test --plugin my-plugin // This creates only models and empty controller, service (without routes)

I wonder if is intended behavior.
If then, I wonder why

P.S. If there’s a way to create group in ./api folder, that would be alternative solution for me :slight_smile:

Are you referring only to models?

As I understand you want to achieve something like this:

Main API /api/shop
which will contain multiple controllers/models/services/routes for:
/category
/products
/orders
/clients
and etc?

You’re right.
Including controllers, models, services.

Folders would be like

api/shop/product
api/shop/order
api/shop/client

or

plugins/shop/api/product
plugins/shop/api/order
plugins/shop/api/client

Currently, it’s impossible to have them grouped as you want, but look how I am grouping them right now to achieve something similar:

image

You can create them by using command:
strapi generate:api order --api=shop

It creates individual files like controller, services, models and appends the newly created routes into routes.json

Note: in that case, I have a single routes.json file.

1 Like

Oh that makes sense!

It would be even better if cli support generating api in this structure :slight_smile:

Anyway I really appreciate your help!

(Edit)
I found the way in cli
strapi generate:api order --api=shop
You made my day

Exactly, this is the command I used to generate all these “nested” APIs. It creates individual files like controller, services, models and appends the newly created routes into routes.json

1 Like

Is there a way to make bootstrap.js work inside ./api folder?

Unfortunately, no, for APIs you can have a single bootstrap.js file located in ./config/functions/bootstrap.js.

But you can have an individual bootstrap.js file per Plugin ./plugins/{plugin-name}/config/functions/bootstrap.js. In that case, you can create a plugin called “Shop” and create multiple APIs inside it like Orders, Products, Clients, etc. But the problem that I noticed when using plugins CLI is that it doesn’t auto-populate the routes.json file with the newly created API. So you must define all the routes manually :expressionless:

It was disabled in March:
https://github.com/strapi/strapi/pull/5586/commits/760e89fb4a7300b0c3c7da8b43e7f2bd14b2cd32
I don’t know what’s the reason for disabling routes generation, since the only issues I found was related to models.

tagging @alexandrebodin and @Pierre_Noel to see if they can explain why (because I don’t know either)

As to the structure, is there a specific reason you want them in /api instead of the plugin? (Core-API?)

https://github.com/strapi/strapi/pull/5586#pullrequestreview-529135554
I also asked this on github. On my local projects I’ve modified it to generate routes automatically inside Plugins.

1 Like

Ah yeah I remember seeing that convo last week (which feels like a year ago)

Hope Alex can respond here to make it clear for those searching for it.

1 Like

Hi, I’m not sure which question I should answer here so I’ll go with: “Why not routes are generated when we generate a model in a plugin”

The answer is that a plugin model doesn’t get a core controller and a core service instance linked to it because we don’t want to create code that a plugin developer don’t want nor add unwanted routes. So by default a model in a plugin is just a model and you add your APIs manually. In the future we might offer a quick way to generate a CRUD API for a model programmatically but this will need some greater changes first.

In v4 the plugin loading will change from a file loading to a plain export from the developper. This means you will be able to organise your code however you want.

Hello @alexandrebodin, thank you for your time

The question is actually:

Why no routes are generated when we generate an API in a plugin.

It’s not related to models at all. It’s related only to generate:api inside plugin.

As I understand the routes generation was intended to be disabled only for this command, which defines the model attributes:
strapi generate:api {api-name} name:string description:text --plugin {plugin-name}

But it also disabled the route generation for this command:
strapi generate:api {api-name} --plugin {plugin-name} - Creating another API inside the existing plugin, in that case, no models attributes were specified here.

My point was about Finding a way to use core controller and service from plugin

@alexandrebodin Can I achieve it on plugin v4 then?

Hi. You will be able to do whatever you want as it will be an export you make so for example this might look like this (not actually the final form but you get the idea)

const { coreApi } = require(‘strapi’)

module.exports = {
controllers: {
myController: coreApi.createController(model)
}
}

That’s still pretty much the same response. the models in a plugin don’t get a core controller or a core service => so not actions => so routes would point to nothing => error.
To add the routes we would need to create controller & services with actual code in it because right now they are empty and not enhance with the core API

2 Likes

Thank you. Till this moment I was thinking that custom plugins are also enhanced by the core API.

Sure, implementing bridge(?) controller is not a big deal.
(But it would be nicer if there’s a helper which generates GraphQL schema and handlers)

Your approach seems perfect for my case. I look forward to the update :slight_smile: