Laravel-json-api: Question: How to add custom action to resource constroller?

Created on 20 Jun 2018  路  11Comments  路  Source: cloudcreativity/laravel-json-api

Hi! Thanks for package. I found nothing in documentation about my question. How I can add custom action to resource controller? For instance: I have PostController, this controller extends JsonApiController, inherits index, create, update, etc. And I want to add 'share' action.

docs tests

All 11 comments

Hi! You can register any route you want using the normal Laravel route registrations. Is your action planning on receiving JSON API payloads and/or returning JSON API payloads?

@lindyhopchris action expects ID as input (post method) and should return shared resource as JSON-API response.

So just write the share action method in the way you would a normal Laravel route. Don't inject any of the JSON API dependencies such as RequestInterface etc as they won't exist (they are bound in the service container via the json-api middleware that is used on JSON API registered routes).

To return a JSON API response, you can use the reply() helper on the controller. This will use the default JSON API to encode the response. If you have multiple JSON APIs and you need to use one that is not the default, set the $api property on your controller to the one you want to use.

This should work but let me know if it doesn't and I can help you work out the bugs. I should probably add this scenario to the tests and docs so that we know it does work as it definitely is something you should be able to do!

Thanks for detailed answer! I'll try it soon.

It works! Thank you!

@tekord is this how you organized the routes?

JsonApi::register('v1', [], function (Api $api, $router) {
    $router->get('foo/me', 'FooController@me'); //must be registered BEFORE the resource controller
    $api->resource('foo', ['controller' => 'FooController']);
});

@edeis53 yes.

@lindyhopchris how to get includes to work on the custom endpoint?

I've loaded the $record just the same as the read() action. Made sure $store->readRecord() includes an EncodingParameters object with the appropriate includes. The record returned has the included records, but the includes are not being outputted by the reply() helper, just the record.

I compared the $record being passed to $this->reply()->content($record) in my custom endpoint routename/me?include=foo and for the regular endpoint /routename/1?include=foo and the $record is identical (all included records are there)

Is there an issue with the validator not working here and excluding the include data?

It's probable that the responses factory (that you access via $this->reply() isn't getting parsed encoding parameters when on a custom endpoint.

This isn't really tested at the moment which is why you've probably stumbled across this! I think as there's a lot of people asking about custom endpoints I need to get this better supported and documented for 1.0. I'll bump it up the to-do list.

in the interm, do you have any suggestions on how I could inject the encoding parameters into the responses factory?

@edeis53 I've just pushed a change to the develop branch that moves the encoding parameters binding to the Laravel container, and uses this when creating the responses factory.

This means when you now use $this->reply() the encoding parameters will be injected.

A quick warning on this - if you haven't validated the query parameters, then the client will get a 500 error when they are resolved out of the container as the parsing into the EncodingParametersInterface object will throw an exception. This shouldn't be a problem as you should be validating anything the client is firing at you anyway!

The develop branch is about to be tagged as 1.0.0-beta.6 (hopefully sometime today).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

osteel picture osteel  路  3Comments

daryledesilva picture daryledesilva  路  6Comments

umbert-cobiro picture umbert-cobiro  路  4Comments

defunctl picture defunctl  路  6Comments

lucianholt97 picture lucianholt97  路  6Comments