1
votes

I'm trying to do pretty much what is explained in https://api-platform.com/docs/core/operations/#expose-a-model-without-any-routes. To stick to that example, I have:

  • An API resource Place with full CRUD functionality
  • Another model Weather that represents the weather of a place and I want to have a GET /places/{id}/weather endpoint to get the weather of a specific place.

The solutions that I came up with and the problems I see in them

  • Having an API Platform independent controller/route that handles this
    • The route is not showing up in the OpenAPI documentation (could implement this myself of course)
    • I don't benefit from the built-in serialization features and have to implement this myself
  • Making Weather a resource and creating it via custom Controller as done in https://api-platform.com/docs/core/operations/#expose-a-model-without-any-routes
    • Weather needs an ID to work (right?)
    • Referencing a non-existant Controller and removing endpoints from the OpenAPI documentation but NOT their routes feels very hacky to me
  • Making Weather a subresource
    • A weather property/reference in my Place resource is incorrect / not needed
    • Weather needs an ID again which is not wanted
  • Making Weather a dedicated API resource and using a custom Controller or DataProvider with the places ID
    • I'm kind of misusing the Place ID for Weather
  • Making Weather a custom representation / output / DTO of Place with a custom route and a custom Controller
    • Weather is not a Place

I currently went with the last solution because I could get rid of the ID in Weather and only needed a text adaption in the OpenAPI documentation. The annotation that I'm using in Place is looking like the following

 * @ApiResource(
 *     itemOperations={
 *         "get",
 *         "delete",
 *         "put",
 *         "patch",
 *         "get_weather"={
 *             "method"="GET",
 *             "path"="/places/{id}/weather",
 *             "controller"=WeatherController::class,
 *             "output"=Weather::class
 *         }
 *     },
 * )

But there must be a better solution for this, right? Am I overlooking something?

I think your solution is OK. I do not understand why you think the output of a GET operation must be a representation of the resource. I think it can be anything that makes sense (is meaningfull in the real world you are modeling) for an operation that makes sense in the context of the resource. - MetaClass