Replies: 8 comments 12 replies
-
|
Just added this alternative from the CustomQuestions plugin, which uses the Should this be the recommended approach for plugins? |
Beta Was this translation helpful? Give feedback.
-
|
We are developing a plugin called ojs-codecheck for OJS We need to create our own custom API endpoints, as extending of the existing endpoint doesn't fit our use case. We also asked about this in the PKP Forum and got the confirmation, that we can keep using the Kind regards |
Beta Was this translation helpful? Give feedback.
-
|
Also very interested how this discussions evolves. I was just looking into updating our PluginTemplate to use Vue.js for managing settings, and end up here, because was not sure how to cleanly add API endpoint(s) to the plugin. |
Beta Was this translation helpful? Give feedback.
-
|
A simpler approach would be to introduce a new hook for plugin to inject custom routes which has no association with any existing one such example implementation at main...touhidurabir:pkp-lib:d11991_main and from plugin we can simply use as Hook::add('APIHandler::endpoints::plugin', function (string $hookName, APIRouter $apiRouter): bool {
$apiRouter->registerPluginApiControllers([
// Allow to have a custom API endpoint as
// BASE_URL/index.php/CONTEXT_PATH/api/v1/custom-plugin-path/
new CustomApiController,
// Allow to have a custom ADMIN API endpoint as
// BASE_URL/index.php/index/api/v1/custom-admin-plugin-path/
new CustomAdminApiController,
]);
return Hook::CONTINUE;
});it uses a strict API controller's handler path uniqueness check so there should be no collision of plugins having same type of path and remove the possibility of action/data leaking of different plugins with same api route path which is possible with the use of However this require some modification to the core . |
Beta Was this translation helpful? Give feedback.
-
|
We moved forward with issue #12050 and POC PR . Any suggestions are highly appreciated . |
Beta Was this translation helpful? Give feedback.
-
|
@touhidurabir @ewhanson And for extending existing endpoint this approach is still recommended approach? |
Beta Was this translation helpful? Give feedback.
-
Proposed SolutionSee the issue Custom API endpoint for plugins and related PRs in the issue description . will be available from 3.5.0-4 and main(upcoming 3.6) . Use Hookuse the hook Hook::add('APIHandler::endpoints::plugin', function (string $hookName, APIRouter $apiRouter): bool {
$apiRouter->registerPluginApiControllers([
// Allow to have a custom API endpoint as
// BASE_URL/index.php/CONTEXT_PATH/api/v1/custom-plugin-path/
new CustomApiController,
]);
return Hook::CONTINUE;
});The When to use (Recommended)
Restrictions
Alternative approach :use the // Allow to have a custom API endpoint as
// BASE_URL/index.php/CONTEXT_PATH/api/v1/custom-plugin-path/
Hook::add('Dispatcher::dispatch', function (string $hookName, array $args): bool {
$request = $args[0]; /** @var PKPRequest $request */
$router = $request->getRouter();
if (!$router instanceof APIRouter) {
return Hook::CONTINUE;
}
$requestPath = $request->getRequestPath();
if (!str_contains($requestPath, 'custom-plugin-path')) {
return Hook::CONTINUE;
}
$controller = new CustomApiController;
$handler = new APIHandler($controller);
// we can get all the registered routes at this point as if need to run any more extra checks
// app('router')->getRoutes();
$router->setHandler($handler);
$handler->runRoutes();
return Hook::ABORT;
});Through the usage of Possible points to reconsiderIt's possible to alter the current implementation very slightly to remove those
|
Beta Was this translation helpful? Give feedback.
-
|
PR has been merged in 3.5/main branch . So this is already available for main branch and will be available from |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
There should be a built-in way for plugins to create custom API endpoints and route them to a custom
APIHandlerwhich ensures that all API middleware is applied and works seamlessly with the useFetch composable.Proposal requirements:
/plugins/generic/my-plugin)GETrequests.APIHandlerorPageHandlerProblem
At the moment, I believe plugins can only create new endpoints off of existing endpoints by hooking into
APIHandler::endpoints::<entity>. However, sometimes a totally new API endpoint is more sensible. The only way to do this that is currently documented is to use theLoadHandlerhook to pass the request to aPageHandler.This works for
GETrequests , which can use authorization policies to restrict access and return JSON. However, if aPUT,POST, orDELETErequest is handled, the CSRF token must also be checked. APageHandlerexpects to find the CSRF token in the request body, but API requests sent by the useFetch composable put the CSRF token into a header atX-Csrf-Token.More importantly, a
PageHandlerdoesn't automatically check for a CSRF token onPUT,POST, orDELETErequests. It would be easy for a plugin developer to forget to apply this security measure.Current Alternatives
Plugins can use the following to workaround this problem:
PageHandler. See example.PageHandlerwill find it. Example:const {data} = useFetch(url, {method: 'POST', body: {...data, csrfToken}}).Beta Was this translation helpful? Give feedback.
All reactions