Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
code challenge 5 solution
Browse files Browse the repository at this point in the history
jschaedl committed Sep 28, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 22c8ed1 commit 33119df
Showing 39 changed files with 656 additions and 339 deletions.
16 changes: 16 additions & 0 deletions CODING-CHALLENGE-6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# RESTful Webservices in Symfony

## Coding Challenge 6 - POST vs. PUT

### Tasks

- implement controllers to create and update attendees and workshops
- both should be possible with JSON and XML

### Solution

- use an `ArgumentValueResolver` to deserialize the request's content
- use the `EntityManager` to save the object into the database
- *CREATE:* use HTTP method `POST`, return an HTTP 201 (Created) status code and
set the `Location` header with the help of the `UrlGenerator`
- *UPDATE:* use HTTP method `PUT`, return an HTTP 204 (No Content) status code and leave the response body empty
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -23,7 +23,8 @@
"symfony/runtime": "6.3.*",
"symfony/serializer": "6.3.*",
"symfony/yaml": "6.3.*",
"webmozart/assert": "^1.11"
"webmozart/assert": "^1.11",
"willdurand/negotiation": "^3.1"
},
"config": {
"allow-plugins": {
112 changes: 84 additions & 28 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions src/Controller/Attendee/ListController.php
Original file line number Diff line number Diff line change
@@ -27,10 +27,8 @@ public function __invoke(Request $request): Response
$request->query->getInt('size', 10)
);

$serializedAttendeeCollection = $this->serializer->serialize($attendeeCollection, 'json');
$serializedAttendeeCollection = $this->serializer->serialize($attendeeCollection, $request->getRequestFormat());

return new Response($serializedAttendeeCollection, Response::HTTP_OK, [
'Content-Type' => 'application/json',
]);
return new Response($serializedAttendeeCollection, Response::HTTP_OK);
}
}
9 changes: 4 additions & 5 deletions src/Controller/Attendee/ReadController.php
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
namespace App\Controller\Attendee;

use App\Entity\Attendee;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
@@ -17,12 +18,10 @@ public function __construct(
) {
}

public function __invoke(Attendee $attendee): Response
public function __invoke(Request $request, Attendee $attendee): Response
{
$serializedAttendee = $this->serializer->serialize($attendee, 'json');
$serializedAttendee = $this->serializer->serialize($attendee, $request->getRequestFormat());

return new Response($serializedAttendee, Response::HTTP_OK, [
'Content-Type' => 'application/json',
]);
return new Response($serializedAttendee, Response::HTTP_OK);
}
}
6 changes: 2 additions & 4 deletions src/Controller/Workshop/ListController.php
Original file line number Diff line number Diff line change
@@ -27,10 +27,8 @@ public function __invoke(Request $request): Response
$request->query->getInt('size', 10)
);

$serializedWorkshopCollection = $this->serializer->serialize($workshopCollection, 'json');
$serializedWorkshopCollection = $this->serializer->serialize($workshopCollection, $request->getRequestFormat());

return new Response($serializedWorkshopCollection, Response::HTTP_OK, [
'Content-Type' => 'application/json',
]);
return new Response($serializedWorkshopCollection, Response::HTTP_OK);
}
}
9 changes: 4 additions & 5 deletions src/Controller/Workshop/ReadController.php
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
namespace App\Controller\Workshop;

use App\Entity\Workshop;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
@@ -17,12 +18,10 @@ public function __construct(
) {
}

public function __invoke(Workshop $workshop): Response
public function __invoke(Request $request, Workshop $workshop): Response
{
$serializedWorkshop = $this->serializer->serialize($workshop, 'json');
$serializedWorkshop = $this->serializer->serialize($workshop, $request->getRequestFormat());

return new Response($serializedWorkshop, Response::HTTP_OK, [
'Content-Type' => 'application/json',
]);
return new Response($serializedWorkshop, Response::HTTP_OK);
}
}
51 changes: 51 additions & 0 deletions src/EventListener/RequestFormatListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace App\EventListener;

use App\Negotiation\ContentNegotiator;
use App\Negotiation\MimeType;
use App\Negotiation\RequestFormat;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

#[AsEventListener(event: KernelEvents::REQUEST, method: 'onKernelRequest', priority: 8)]
final class RequestFormatListener
{
private array $formats = [
RequestFormat::JSON => MimeType::JSON,
RequestFormat::JSON_HAL => MimeType::JSON_HAL,
RequestFormat::XML => MimeType::XML,
];

public function __construct(
private ContentNegotiator $contentNegotiator
) {
}

public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();

$this->addRequestFormats($request, $this->formats);

$request->setRequestFormat(
$this->contentNegotiator->getNegotiatedRequestFormat()
);
}

/**
* Adds the supported formats to the request.
*
* This is necessary for {@see Request::getMimeType} to work.
*/
private function addRequestFormats(Request $request, array $formats): void
{
foreach ($formats as $format => $mimeType) {
$request->setFormat($format, $mimeType);
}
}
}
Loading

0 comments on commit 33119df

Please sign in to comment.