GET /jobs HTTP/1.1 Host: api.example.com Accept: application/vnd.example.api+json;version=2
vnd.
the part is dictated by the requirements of rfc4288-3.2 , and is used to specify the types of data provided by the supplier. In vnd.*
data type can be provided to IANA and registered as an official type. In theory, you could just use application/json
and add a version parameter, but since the json standard does not allow such liberties, this would not be entirely correct use.Accept
header. To achieve this, you need to accept Accept
and create routing rules that can use this information. class ApiController extends Controller { public function getJobsAction() { $jobs = $this->get('wjzijderveld_api.job_manager')->getJobs(); return new Response(json_encode($jobs)); } public function getJobAction($id) { $job = $this->get('wjzijderveld_api.job_manager')->getJob($id); return new Response(json_encode($job)); } }
class Api2Controller extends ApiController { public function getJobsAction() { $jobs = $this->get('wjzijderveld_api.job_manager')->getJobs(); usort($jobs, function ($a, $b) { return strcmp($a['title'], $b['title']); }); return new Response(json_encode($jobs)); } }
BaseBundle
with custom routing. To be able to switch to the desired controller, we must determine the requested version. For this, I expanded the standard classes Router
and RequestContext
, I defined new classes in parameters.yml. router.class: Wjzijderveld\BaseBundle\Router\ApiRouter router.options.matcher_class: Wjzijderveld\BaseBundle\Router\VersionMatcher router.request_context.class: Wjzijderveld\BaseBundle\Router\RequestContext
Accept
header and expose the version in RequestContext
. Thanks to symfony, for being such a cake and has an AcceptHeader
implementation: public function matchRequest(Request $request) { $acceptHeader = AcceptHeader::fromString($request->headers->get('Accept'))->get($this->acceptHeader); // .. if (null === ($version = $acceptHeader->getAttribute('version'))) { return $this->match($request->getPathInfo()); } $this->getContext()->setApiVersion($version); return $this->match($request->getPathInfo()); }
# Version 1 api1_get_jobs: path: "/jobs" defaults: _controller: "WjzijderveldApiBundle:Api:getJobs" condition: "context.getApiVersion() === '1'" # Version 2 api2_get_jobs: path: "/jobs" defaults: _controller: "WjzijderveldApiBundle:Api2:getJobs" condition: "context.getApiVersion() === '2'"
Source: https://habr.com/ru/post/240817/
All Articles