Reputation: 71
In my Api Platform Symfony Application, I have a class called Membership
, which represents a many-to-many relationship between Users and Communities. It contains only two routes: DELETE, for user leaving a community, and POST, for joining.
Membership
entity class:
#[ORM\Entity(repositoryClass: MembershipRepository::class)]
#[ApiResource(
description: "A representation of a single user being a member of a given subreddit.",
operations: [
new Post(
uriTemplate: '/subreddits/{subreddit_id}/join.{_format}',
uriVariables: [
'subreddit_id' => new Link(
fromClass: Community::class,
fromProperty: 'members',
),
],
security: "is_authenticated()",
securityMessage: "Only logged-in users can join a subreddit.",
denormalizationContext: ['groups' => ['membership:create']],
// openapiContext: ['requestBody' => false],
// openapiContext: ['requestBody' => ['content' => ['application/ld+json' => ['schema' => ['type' => 'object']]]]],
input: Community::class,
provider: CommunityStateProvider::class,
processor: MembershipPersistStateProcessor::class,
),
new Delete(
uriTemplate: '/subreddits/{subreddit_id}/leave.{_format}',
uriVariables: [
'subreddit_id' => new Link(
fromClass: Community::class,
fromProperty: 'members'
),
],
security: "is_authenticated()",
securityMessage: "Only logged-in users can leave a subreddit.",
input: Community::class,
provider: CommunityStateProvider::class,
processor: MembershipRemoveStateProcessor::class,
),
],
)]
#[UniqueEntity(fields: ['subreddit', 'member'], message: "You are already a member of this subreddit.")]
class Membership
Since user data is extracted from the access token and community data is passed through URI variable, there is no need for a JSON body.
And...
$response = $client->request('POST', 'api/subreddits/'.$community->getId().'/join', [
'headers' => [
'Content-Type' => 'application/ld+json',
'Authorization' => 'Bearer ' . $token,
],
'json' => [],
]);
...looks absolutely terrible.
Based on the pull requests I found within the API Platform repository (pull), allowing empty requests for POST and PUT should be possible by setting the content-type to '', yet all configurations I tried only led to more errors. Is there a way to achieve this?
Upvotes: 0
Views: 248
Reputation: 71
Solved. The main issue here is that deserializer checks for the content-type header and then throws exceptions. If you wish to allow your route to accept empty requests, you can disable deserializer events by setting the deserialize flag. Additionally, it might be a good idea to remove the JSON body from Swagger by setting requestBody to false as well. (Note: there is a ominous leftover "todo: remove in 4.0", so it might become deprecated).
operations: [
new Post(
uriTemplate: '/subreddits/{subreddit_id}/join.{_format}',
uriVariables: [
'subreddit_id' => new Link(
fromClass: Community::class,
fromProperty: 'members',
),
],
openapiContext: ['requestBody' => false],
deserialize: false,
),
Upvotes: 0