V8-archive: Different hooks for every project

Created on 11 Dec 2019  路  14Comments  路  Source: directus/v8-archive

Hi, i'm currently using Directus v7. It's the first time I use hooks. There is a way to have different hooks for each project. Because if in my projects I have some collections with the same name. I can't understand how to distinguish them.

Example of my hook:

return [ 'actions' => [ 'item.update.courses' => function (array $data) { //code } ] ];

Expected:

return [ 'actions' => [ 'project1.item.update.courses' => function (array $data) { //code }, 'project2.item.update.courses' => function (array $data) { //alternative code } ] ];

question documentation api

All 14 comments

@marcocala90 - You can define your project-related hooks into your project config file. This way you will not require the project_name in the hook name.

@rijkvanzanten - As per my knowledge; we already have a collection name as a directory name in api/public/extensions/custom/hooks directory. Maybe we should add a project directory also api/public/extensions/custom/hooks/{project_name}/{collection_name} - so we can execute the hooks based on the current project.

Let me know your thoughts on this :)

@bjgajjar We should lift it up one level by considering all the ways we have to make _all_ the extensions project scoped. I like to have project-scoped interfaces / endpoints etc too

@rijkvanzanten - Thanks for highlighting other points. But at first glance, it seems like all of these features can be handled with api/public/extensions/custom/hooks/{project_name}/{collection_name} structure which LGTM.

Did you find something wrong in it?

Yes, we need scoped extensions for every extension type regardless, so I'd rather find a single solution that works for all

Let me provide a solution that may work for all commonly.

Currently, the folder structure is api/public/extensions/custom.

The custom folder contains below folders.

  • Auth
  • Endpoints
  • Hashers
  • Hooks
  • Interfaces
  • Layouts
  • Mail
  • Migrations
  • Modules

api/public/extensions/custom/hooks/{project_name}/{collection_name} structure which LGTM.

Instead of this, we should rename the custom with {project_name}. All of the above-defined folders will be inside this folder.

Every time when the new project will configured; system will automatically generate these folders.

Example

  • The user tried to configure the project directus. The system will automatically generate the folder public/extensions/directus as well as all of these folders[auth, endpoints, hooks etc.] inside the directus folder.

On every new project creation, the folder of that project will be created inside public/extensions.


we need scoped extensions for every extension type

Extensions are different from these hooks and endpoints. As hooks are based on the projects. But the extensions will be common for all projects.

So to check which extensions are enabled in the current project, we should introduce another directus core table - directus_entensions. So it is completely different from this stuff.

We should consider it separately from these. Though it will be placed inside the extensions folder.

Extensions are different from these hooks and endpoints. As hooks are based on the projects. But the extensions will be common for all projects.

This is false. _Extensions_ is a term for all above listed types (endpoints / hooks / modules / etc). All of those types should be able to be scoped to a project.

So to check which extensions are enabled in the current project, we should introduce another directus core table - directus_entensions. So it is completely different from this stuff.

I don't think adding a new table is the way to solve this. I'd rather do it based on the filesystem.

This is false. Extensions is a term for all above listed types (endpoints / hooks / modules / etc). All of those types should be able to be scoped to a project.

But don't you think so that adding _Extensions_ globally will be a good approach? As the user can generate it globally and just need to enable it based on their requirements for different projects.

By doing this, we are enlarging the scope of _Extensions_.

Let me know if you have another approach :)

The plan is to support both 馃檪 You should be able to either have the extension global _or_ scoped

@WoLfulus - Let's have a conclusion on this. Can you please provide your approach here?

I'd enable extensions through config file instead. Otherwise we'll end up with a lot of extension copies for each existing project.

Please correct me if I'm wrong.

The way I see it right now:

  • Extensions are scoped on the file system based on folder with project names
    /:project/interfaces/custom-text-input
  • There is a special global folder that makes extensions available to every project
  • We add a POST /extensions/:type endpoint that allows you to post a .zip folder of the extension
  • We add a DELETE /extensions/:type/:name endpoint that allows you to delete an extension

We could use a folder structure like:

/extensions/
  system/
  global/
  scoped/
    my-project/
      interfaces/
      layouts/
      modules/
      hooks/
      storage-adapters/
      sso-providers/

  • In the project root by default
  • Configurable to be anywhere (for Docker / other server setups?)
  • Make sure global hooks return the project it was called from

Is there any progress on this? I have a multi-tenant Directus install and need to be able to define hooks per project/tenant. Adding the hooks into the config file seems to work, but I have to have the function in each action. I'm not very good with PHP, so maybe I'm doing something wrong.

  • Adding function sending ($collectionName, $data) { $container = \Directus\Application\Application::getInstance(); // Monolog\Logger instance $logger = $container->fromContainer('logger'); $logger->info(json_encode($data)); } to the top of the file (between <?php and return works in the normal hooks directory location. I then can just do something like 'actions' => [ 'item.update' => sending] and the logging is successful.

  • Putting that function directly into the hooks>action part of the config/{project_name}.php file also works.

  • Putting that function above the return statement and calling it like 'item.update' => sending within the config/{project_name}.php file causes the site to give me a 500 error message.

  • Putting the function in a different file (chown'd to www-data) and using require 'send_function.php'; above the return file also causes the site to give me a 500 error message.

Whenever any item in the entire project is created/updated/deleted, I need to send a Guzzle POST to my drone installation to have Gatsby re-build the site to reflect the new data state in Directus, so the function is the same and it would be a shame to need to have that function written three times for all the actions of item.create item.update and item.delete. Is there a better way to accomplish this on a per-project basis that I'm missing?

You can add hooks in the project's config file as well, which makes it per project 馃檪

You can add hooks in the project's config file as well, which makes it per project 馃檪

Yes, I was able to add them into the actual hooks block in the project's config. But I wasn't able to reference a function that is defined outside of the return block. Requiring a file or defining a function in the project config file (above the return block) causes the site to give a 500 error. Doing either of these in the public>extensions>custom>hooks files seems to work, but not per project. Can anyone give me some pointers for how to call the same function for multiple actions in the hooks of a project config?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

metalmarco picture metalmarco  路  3Comments

andgar2010 picture andgar2010  路  3Comments

binary-koan picture binary-koan  路  3Comments

24js picture 24js  路  3Comments

vuhrmeister picture vuhrmeister  路  3Comments