Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow registration of custom actions #36

Open
tobyzerner opened this issue Sep 4, 2021 · 3 comments
Open

Allow registration of custom actions #36

tobyzerner opened this issue Sep 4, 2021 · 3 comments
Labels
enhancement New feature or request
Milestone

Comments

@tobyzerner
Copy link
Owner

tobyzerner commented Sep 4, 2021

For implementing behavior not defined by the spec.

Something like:

$type->resourceAction('publish', function ($model, Context $context) {
    $model->publish();
    return $model;
})
    ->authorized(...);

$type->collectionAction('purge', function (Context $context) {
    Post::delete();
    return new Response(204);
})
    ->method('delete')
    ->authorized(...);

Call via:

POST /api/posts/1/actions/publish
DELETE /api/posts/actions/purge
@tobyzerner tobyzerner added the enhancement New feature or request label Sep 4, 2021
@tobyzerner tobyzerner added this to the v1.1 milestone Jun 21, 2023
@tobyzerner
Copy link
Owner Author

Now technically possible with custom endpoints in v1.0. Providing some Action endpoints out of the box planned for v1.1

@bertramakers
Copy link
Contributor

I'd be interested in this for some of our use-cases. Can you expand on how it is already possible with custom endpoints?

@tobyzerner
Copy link
Owner Author

tobyzerner commented Aug 26, 2023

Create a new implementation of Tobyz\JsonApiServer\Endpoint\EndpointInterface - look at the existing implementations for examples (Show, Create, etc). Something like this:

class MyAction implements EndpointInterface
{
    public static function make(): static
    {
        return new static();
    }

    public function handle(Context $context): ?ResponseInterface
    {
        // Endpoint to handle POST /{resource}/my-action

        $segments = explode('/', $context->path());
        if (count($segments) !== 2 || $segments[1] !== 'my-action') {
            return null;
        }

        if ($context->method() !== 'POST') {
            throw new MethodNotAllowedException();
        }

        // Do stuff with $context->resource, $context->body(), etc

        return new Response(204);
    }
}

Then just add a new instance of your endpoint to the endpoints() array for any resources that should support it:

public function endpoints()
{
    return [Endpoint\Show::make(), MyAction::make()];
}

For 1.1 I'm planning to add generic action endpoints that you can instantiate with an action name and a handler function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants