-
Notifications
You must be signed in to change notification settings - Fork 12
Attributes not being mapped to controller #115
Comments
The problem here is that you defined an object parameter with the name Probably what you want is to add an argument passing the whole object to the controller. You can either turn off hydration and expect a Option 1: public function __invoke(\stdClass $body): \stdClass // Don't return Response objects, SwaggerBundle will create them
{
// Do stuff
} Option 2: paths:
/some-path
parameters:
- in: body
name: myObject
schema: { $ref: '#/definitions/MyDtoType' }
definitions:
MyDtoType:
type: object
properties:
slug:
type: string
# Etc. class MyDtoType
{
private $slug;
// Etc..
} public function __invoke(MyDtoType $myObject): MaybeSomeOtherType // Don't return Response objects, SwaggerBundle will create them
{
// Do stuff
} See: |
Unless I'm misunderstanding something, I think swagger-bundle may be behaving differently than the swagger spec. From https://swagger.io/docs/specification/2-0/describing-request-body/: I don't think that body name should be used at all. The value of |
Well, you are free to name it anything you want (including The parameter -> controller method argument mapping internals is not actually SwaggerBundle behavior, but Symfony's FrameworkBundle doing. SwaggerBundle just sets the appropriate attributes on the request object. |
My point is that the body parameter should not be referenced by swagger-bundle at all. Instead, the attributes that would be created would be top level. For example Symfony matches based on naming, not based on order. Therefore simply adding them all as attributes |
I see what you are saying but I feel like you would be better off just naming the object Consider this example where the path contains the original slug, and the body contains a new value for parameters:
- in: path
name: slug
type: string
- in: body
name: body
type: object
properties:
name: { type: string }
slug: { type: string } Both attributes (and thus arguments) would be named |
Oh I agree, which is why I completely dislike using the request attributes except when using object hydration. I think that the json should be decoded and added to This let's us keep in line with Symfony 100%. It also means controllers are no longer dependent upon swagger-bundle. |
You can already have the request passed if you really want: public function __invoke(Request $request)
{
// Do stuff with $request->attributes->get('body'); and whatever else
} And you could also return Response objects, but the event listeners that SwaggerBundle uses for dehydration, response validation, and serialization won't work, due a limitation of the HttpKernel: // call controller
$response = call_user_func_array($controller, $arguments);
// view
if (!$response instanceof Response) {
// Dispatch more events
} You can, if you want use SwaggerBundles |
I know I can use the Request object already, but it is not being used in a standard way due to the I'm actually not planning on using the dehydration, response validation or serialization functionality. I see that as more RAD functionality and we are not looking to do that. Is there any reason though to not populate the |
The routing takes care of populating the "standard" request parameter bags. These are still accessible as they would be with any other RouteLoader. The So it makes no sense putting deserialized JSON in there. In the standard way, decoding a JSON post in your controller would have to look like this: $json = json_decode($request->getContents()); You can still do that if you want, but why would you if you can just use the body parameter? Even with hydration turned off, SwaggerBundle will do parameter coercion, to make for example "0" into FALSE, if dictated by the schema. The result of the coercion is added as an attribute to keep the original value available in the Request object. There is a possible collision with path parameters, but only if you declare a type other than string which is unlikely. |
I'm having an issue with the mapping of the request body to the controller action. Currently it's telling me my first parameter is null and thus it can't set it.
For example:
Am I doing something wrong, or is there a bug?
The text was updated successfully, but these errors were encountered: