laminas-api-tools / api-tools-hal

Laminas Module providing Hypermedia Application Language assets and rendering
https://api-tools.getlaminas.org/documentation
BSD 3-Clause "New" or "Revised" License
6 stars 12 forks source link

Would be nice to allow multiple identifiers for a route #23

Open weierophinney opened 4 years ago

weierophinney commented 4 years ago

I think this would be a useful feature but I'm also open to feedback on how I might be doing it wrong or should be doing something differently. I have a route which includes 3 identifiers. My route essentially looks like

/api/apiname/resource/:resourceId[/subtype1/:subtype1/subtype2/:subtype2]

I don't really want to make another resource which was just resource id and subtype 1, and I don't think putting in 2 optional parts in the route is a good way to go. It doesn't appear that I can set any more than a single string as the identifier. In the example above, the HAL links for the entity won't include both subtype1 and subtype2, but does contain up to :resourceId.

If route identifier were allowed to be an array, it seems that the above would be possible, but considering the number of places that this touches, I wanted to get some feedback on it before going forward with a change or PR.

To me, it seems this could be a good idea and I don't see a problem with being able to support it, but would appreciate feedback.


Originally posted by @dstockto at https://github.com/zfcampus/zf-hal/issues/36

weierophinney commented 4 years ago

You can do this with RPC calls. See https://github.com/zfcampus/zf-apigility-doctrine/blob/master/src/Server/Controller/RpcController.php for a working example of /resource/resource_id/field/field_id

Anything deeper than one should be referenced as

/field_resource/field_resource_id


Originally posted by @TomHAnderson at https://github.com/zfcampus/zf-hal/issues/36#issuecomment-44454811

weierophinney commented 4 years ago

@dstockto Have you given it a try yet? One other possibility is to use a combination identifier, and split it in your resource. As an example, your route would be /api/apiname/resource[/:resourceId], but the contents of :resourceId would be something like abc-123. Your resource class would then split this into abc and 123, allowing you to get the different keys. This has the added benefit that it would continue to work with the current code.


Originally posted by @weierophinney at https://github.com/zfcampus/zf-hal/issues/36#issuecomment-68790147

weierophinney commented 4 years ago

Apigility Doctrine supports multi-key splitting by default using the '.' separator, therefore supporting a route like this: /orderdetails/num.code. The DoctrineResource is able to query properly the DB, constructing the entity properly, the problem though is the HAL rendering. If I configure the 'metadata_map' for the resource with 'entity_identifier_name=num' the rendering is done properly but the links it builds are missing the second param (i.e. /orderdetails/num); if I put 'entity_identifier_name=num.code' the request returns the error "Unable to determine entity identifier for object of type \"Entity\Orderdetails\"; no fields matching 'num.code'".

Of course a very simple callback on event 'renderEntity' pushing the composed key in the 'self' link solves the problem (literally 5 lines of code).

It would be nice though to have the functionality available out of the box from the service configuration.


Originally posted by @MassiAtZend at https://github.com/zfcampus/zf-hal/issues/36#issuecomment-146830648