Skip to content

Instantly share code, notes, and snippets.

@sdieunidou
Last active September 7, 2018 11:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sdieunidou/d17411882355985b18f28be817a02f28 to your computer and use it in GitHub Desktop.
Save sdieunidou/d17411882355985b18f28be817a02f28 to your computer and use it in GitHub Desktop.
Api.md

Initialiser une API Rest, avec la ressource /api/tweets. Les méthodes suivantes seront implémentés :

  • cget(): retourne la liste de tous les tweets
  • get($id): retourne un tweet par son ID
  • post(): création d'un Tweet

De nombreux bundles existent, nous utiliserons ici FOS Rest Bundle.

Liens:

Installation FOSRestBundle

$ composer require friendsofsymfony/rest-bundle

Et ajouter dans app/AppKernel.php :

        $bundles = array(
            // ...
            new FOS\RestBundle\FOSRestBundle(),
        );

Activer le serializer de Symfony:

# app/config/config.yml
framework:
    serializer:      { enable_annotations: true }

Et la configuration du bundle :

# app/config/config.yml
fos_rest:
    body_listener: true
    param_fetcher_listener: true
    view:
        view_response_listener: 'force'
        empty_content: 204
        formats:
            json : true
    format_listener:
        enabled: true
        rules:
            - { path: '^/api', priorities: ['json'], fallback_format: json, prefer_extension: false }
            - { path: '^/', stop: true }

Création de notre controller API :

<?php

namespace AppBundle\Controller\Api;

use AppBundle\Entity\Tweet;
use AppBundle\Form\Type\TweetType;
use FOS\RestBundle\Controller\Annotations as FOSRest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\View\View;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\HttpFoundation\Response;

/**
 * TweetController.
 *
 * @FOSRest\Route(path="/api/tweets")
 */
class TweetController extends FOSRestController
{
    /**
     * @FOSRest\View()
     * @FOSRest\Get("/")
     *
     * @ApiDoc(
     *  section="Tweets",
     *  description="Returns a collection of Tweets"
     * )
     *
     * @return Tweet[]
     */
    public function cgetAction()
    {
        return $this->getTweetManager()->all();
    }

    /**
     * @FOSRest\View()
     * @FOSRest\Get("/{id}")
     *
     * @ApiDoc(
     *  section="Tweets",
     *  description="Get a Tweet",
     *  output="AppBundle\Entity\Tweet"
     * )
     *
     * @return Tweet
     */
    public function getAction(Tweet $tweet)
    {
        return $tweet;
    }

    /**
     * @FOSRest\Post("/")
     * @FOSRest\View(statusCode=201)
     *
     * @ApiDoc(
     *  section="Tweets",
     *  description="Create a new Tweet",
     *  input="AppBundle\Form\Type\TweetType",
     *  output="AppBundle\Entity\Tweet"
     * )
     *
     * @param Request $request
     *
     * @return Form|Tweet
     */
    public function postAction(Request $request)
    {
        $form = $this->get('form.factory')->createNamed('', TweetType::class, $this->getTweetManager()->create(), [
            'csrf_protection' => false,
        ]);
        $form->submit($request->request->all());

        if ($form->isSubmitted() && $form->isValid()) {
            $this->getTweetManager()->save($form->getData());

            return $form->getData();
        }

        return new View($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * @return \AppBundle\Manager\TweetManager
     */
    private function getTweetManager()
    {
        return $this->get('app.tweet_manager');
    }
}

Serialization

Créons un serializer pour notre classe Tweet :

services:
    app.normalizer.tweet:
        class: AppBundle\Serializer\Normalizer\TweetNormalizer
        tags:
            - { name: serializer.normalizer }
<?php
namespace AppBundle\Serializer\Normalizer;

use AppBundle\Entity\Tweet;

/**
 * TweetNormalizer.
 */
class TweetNormalizer extends AbstractNormalizer
{
    /**
     * {@inheritdoc}
     */
    public function normalize($object, $format = null, array $context = [])
    {
        /* @var User $object */
        return [
            'id' => $object->getId(),
            'message' => $object->getMessage(),
            'createdAt' => $object->getCreatedAt()->format('d/m/Y H:i:s'),
            'isEnabled' => $object->isEnabled(),
        ];
    }
    /**
     * {@inheritdoc}
     */
    public function supportsNormalization($data, $format = null)
    {
        return $data instanceof Tweet;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment