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

Prevent loading associations in ApiResponse(associations: $var) #537

Closed
manuelpeiso opened this issue Feb 15, 2024 · 10 comments
Closed

Prevent loading associations in ApiResponse(associations: $var) #537

manuelpeiso opened this issue Feb 15, 2024 · 10 comments
Labels
enhancement New feature or request question Further information is requested
Milestone

Comments

@manuelpeiso
Copy link
Contributor

manuelpeiso commented Feb 15, 2024

Describe the bug
I have this index action in my BethroomsController class:

#[OpenApiPaginator]
	#[Get('bethrooms')]
	public function index(
		BethroomSearcher $searcher
	) {
		.....
	}

This automatically generate a response like this one in swagger, wish is exactly what I want:

{
  "collection": {
    "url": "/collection",
    "count": 50,
    "pages": 20,
    "total": 200,
    "next": "/collection?page=:number",
    "prev": "/collection?page=:number",
    "first": "/collection?page=:number",
    "last": "/collection?page=:number"
  },
  "data": [
    {
      "id": "....",
      ........
    }
  ]
}

Then I create this new action in the same controller:

#[OpenApiPaginator]
	#[Get('homes/{home_id}/bethdrooms')]
	public function homeBethrooms(
		BethroomSearcher $searcher
	) {
		.......
	}

And the response in the swagger is string, which is wrong, I want the same response than the other example due to the response is a list of bethrooms.
I tried using #[OpenApiResponse(schemaType: 'array', ref: '#/components/schemas/Bethroom')]
but this response is an array of Entities without the collection key
I also tried #[OpenApiResponse(schemaType: 'array', associations: ['table' => 'Bethrooms','whiteList' => []])]
and this create a response similar that the one I am expecting but again it force me to load at least one association and I don't want loading any association.

I have cakephp 4.5 and cakephp-swagger-bake 2.1

@cnizzardini
Copy link
Owner

cnizzardini commented Feb 16, 2024

So you are wanting a paginated style response (like in your index action) within the same controller but from another action within this controller. Am I understanding what you are trying to achieve? But it seems you are decorating your responses maybe? Hard to know without having the same level of knowledge within your application...

I tried using #[OpenApiResponse(schemaType: 'array', ref: '#/components/schemas/ActivityInstance')]
but this response is an array of Entities without the collection key

Yes, this will overwrite the schema reference and replace it with what you defined in OpenApiResponse::ref. This is explicitly designed for just that use-case.

I also tried #[OpenApiResponse(schemaType: 'array', associations: ['table' => 'ActivityInstances','whiteList' => []])]
and this create a response similar that the one I am expecting but again it force me to load at least one association and I don't want loading any association.

Yes, this is how what you are desiring is generally achieved. What is the problem with loading associations? CakePHP ORM is designed around associations and so this plugin enables developers to express those associations in OpenAPI.

I have cakephp 4.5 and cakephp-swagger-bake 2.1

Version 2.1 of this library is pretty old. It's on 2.5.8 in the 2.x branch. Are you certain that's the version you are on? If so, please upgrade as I will only support recent releases.

Have you considered using events?

Next have you considered using Event Listeners to accomplish your task. If you are doing something unique with those injected dependencies and result decorators, then you might need to do some additional processing. Those events give you complete control over the final OpenAPI schema: https://github.com/cnizzardini/cakephp-swagger-bake/blob/master/docs/events.md

@cnizzardini cnizzardini added the question Further information is requested label Feb 16, 2024
@manuelpeiso
Copy link
Contributor Author

So you are wanting a paginated style response (like in your index action) within the same controller but from another action within this controller. Am I understanding what you are trying to achieve?
Yes, this is exactly what I want to achieve. I don't want to load associations because the actual response of that endpoint doesn't have the associations loaded and I want my swagger represents the exact response of my endpoint.
I am just wandering if there is any 'easy' way to do that, just like the index that do it by default, or when you add associations that also create a very pretty response with the associations loaded.
I did try the Event Listeners, but I want to use it only if necessary.

@cnizzardini
Copy link
Owner

cnizzardini commented Feb 16, 2024

What about this point I made?

Version 2.1 of this library is pretty old. It's on 2.5.8 in the 2.x branch. Are you certain that's the version you are on? If so, please upgrade as I will only support recent releases.

Also, are you using MixerAPI or just SwaggerBake?

@manuelpeiso
Copy link
Contributor Author

Sorry for my mistake, I have installed v2.5.8 and I am using MixerApi v1.1.7 wirh cakephp ^4.5-RC1.

@cnizzardini
Copy link
Owner

Okay no problem, just making sure you are not on an ancient version.

So if I am understanding correctly, you really only want to display the base model? In otherwords you'd like to do something like this:

#[OpenApiResponse(schemaType: 'array', associations: ['whiteList' => []])]

And by passing in an empty whiteList the library would not include any associations?

@manuelpeiso
Copy link
Contributor Author

Exactly, I mean, all the endpoint that returns a collection of data in my system are paginated, so any time I create an endpoint I need the collection key and an array of Model in the response.
At the beginning I though that, as the index endpoint, only adding

#[OpenApiPaginator]
#[Get('route')]

like in the index would be enough, but then I realized that this approach only works for the crud endpoints.

So yes
#[OpenApiResponse(schemaType: 'array', associations: ['whiteList' => []])]
if this could return my Model with no associations would be great, but it does the opposite, it returns all the associations.

@cnizzardini
Copy link
Owner

cnizzardini commented Feb 16, 2024

If that is the case I would submit a PR.

This seems like an easy change here: https://github.com/cnizzardini/cakephp-swagger-bake/blob/2.x/src/Lib/Operation/OperationResponseAssociation.php#L74

Then add single test case in here https://github.com/cnizzardini/cakephp-swagger-bake/blob/2.x/tests/TestCase/Lib/Operation/OperationResponseAssociationTest.php (I don't mind assisting on this part).

Last updating the documentation here: https://github.com/cnizzardini/cakephp-swagger-bake/blob/2.x/docs/attributes.md (also don't mind helping on this one)

I don't believe passing an empty array can work though, as it would possibly be a breaking change, instead the following would be non-breaking:

#[OpenApiResponse(schemaType: 'array', associations: ['whiteList' => false])]

Then in the code you can do a strict === false check and not load the associations. If you don't want to submit this PR I will still add the feature request, but it may be months before I get to it.

@manuelpeiso
Copy link
Contributor Author

Awsome, I will do that for sure. Thank you!

@manuelpeiso
Copy link
Contributor Author

I already created the PR: #538
Anything you need from me to update in the code I pushed just let me know.

@cnizzardini cnizzardini changed the title How to load array of entity without associations but including the collection key? Prevent loading associations in ApiResponse(associations: $var) Feb 19, 2024
@cnizzardini cnizzardini modified the milestones: v2.5.9, v3.0.1 Feb 19, 2024
@cnizzardini
Copy link
Owner

Okay this is released: https://github.com/cnizzardini/cakephp-swagger-bake/releases/tag/v2.5.9

@cnizzardini cnizzardini added the enhancement New feature or request label Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants