{"id":557,"date":"2016-04-11T19:26:42","date_gmt":"2016-04-11T18:26:42","guid":{"rendered":"http:\/\/louis.hatier.me\/blog\/?p=557"},"modified":"2021-03-05T22:23:08","modified_gmt":"2021-03-05T21:23:08","slug":"developper-api-rest-symfony-3","status":"publish","type":"post","link":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/","title":{"rendered":"D\u00e9velopper une API REST avec Symfony 3"},"content":{"rendered":"<p><a href=\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\" data-rel=\"lightbox-gallery-UCcs8jjY\" data-rl_title=\"\" data-rl_caption=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-513 size-full\" title=\"\" src=\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\" alt=\"Logo Symfony\" width=\"219\" height=\"80\"><\/a>Symfony (2 et 3) permet de publier tr\u00e8s facilement une <strong>API REST<\/strong> \u00e0 l\u2019aide de diff\u00e9rents <em>bundles<\/em>.<br \/>\nCette API peut \u00eatre \u00e9galement fourni d\u2019une documentation g\u00e9n\u00e9r\u00e9e dynamiquement.<\/p>\n<p>L\u2019id\u00e9e est de cr\u00e9er une API REST simple, qui met \u00e0 disposition une liste d\u2019utilisateurs et de commentaires.<br \/>\nCommen\u00e7ons par g\u00e9n\u00e9rer un nouveau projet.<\/p>\n<p><!--more--><\/p>\n<pre><code class=\"no-highlight\">cd \/var\/www\/\nsymfony new symfony-rest\ncd symfony-rest\/\n<\/code><\/pre>\n<p>Les bundles qui vont nous permettre d\u2019avoir une API fonctionnelle sont les suivants : <strong>FOSRestBundle<\/strong> et <strong>JMSSerializerBundle<\/strong>.<br \/>\nIl faut donc les ajouter via <em>Composer<\/em> et les renseigner dans le tableau de la fonction <code>registerBundles<\/code> du fichier <code>app\/AppKernel.php<\/code>.<\/p>\n<pre><code class=\"no-highlight\">composer require friendsofsymfony\/rest-bundle\ncomposer require jms\/serializer-bundle\n<\/code><\/pre>\n<pre><code class=\"php\">new FOS\\RestBundle\\FOSRestBundle(),\nnew JMS\\SerializerBundle\\JMSSerializerBundle(),\n<\/code><\/pre>\n<p>Nous allons ensuite d\u00e9finir les param\u00e8tres du bundle FOSRestBundle dans le fichier <code>app\/config\/config.yml<\/code>.<\/p>\n<pre><code class=\"yaml\"># FOSRestBundle\nfos_rest:\n    param_fetcher_listener: true\n    body_listener: true\n    format_listener: true\n    view:\n        view_response_listener: 'force'\n        formats:\n            xml: true\n            json : true\n        templating_formats:\n            html: true\n        force_redirects:\n            html: true\n        failed_validation: HTTP_BAD_REQUEST\n        default_engine: twig\n    routing_loader:\n        default_format: json\n<\/code><\/pre>\n<p>Il nous reste \u00e0 d\u00e9finir le routing dans un fichier s\u00e9par\u00e9.<br \/>\nD\u00e9claration de l\u2019import du nouveau fichier dans <code>app\/config\/routing.yml<\/code>, en pr\u00e9fixant l\u2019url par \u00ab\u00a0\/api\/\u00a0\u00bb<\/p>\n<pre><code class=\"yaml\">api:\n    resource: api_routes.yml\n    type: rest\n    prefix: \/api\/\n<\/code><\/pre>\n<p>Contenu du fichier <code>app\/config\/api_routes.yml<\/code> :<\/p>\n<pre><code class=\"yaml\">users:\n    resource: AppBundle\\Controller\\UsersController\n    type:     rest\n\ncomments:\n    resource: AppBundle\\Controller\\CommentsController\n    type:     rest\n<\/code><\/pre>\n<p>Il nous faut cr\u00e9er une entity User et son repository, avec les champs dont vous avez besoin (nom, email, etc.).<br \/>\nPuis \u00e9crire le contenu de nos controllers, voici un exemple avec <code>UsersController.php<\/code><\/p>\n<pre><code class=\"php\">namespace AppBundle\\Controller;\n\nuse AppBundle\\Entity\\User;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller;\n\nclass UsersController extends Controller\n{\n    \/**\n     * @return array\n     *\/\n    public function getUsersAction()\n    {\n        $em = $this-&gt;getDoctrine()-&gt;getManager();\n        $users = $em-&gt;getRepository('AppBundle:User')-&gt;findAll();\n\n        return array('users' =&gt; $users);\n    }\n\n    \/**\n     * @param User $user\n     * @return array\n     *\/\n    public function getUserAction(User $user)\n    {\n        return array('user' =&gt; $user);\n    }\n}\n<\/code><\/pre>\n<p>Ce bout de code nous permet de mettre \u00e0 disposition la liste des utilisateurs, ou bien un utilisateur pr\u00e9cis.<br \/>\nEn acc\u00e9dant \u00e0 http:\/\/localhost\/symfony-rest\/api\/users, l\u2019API REST retourne une collection d\u2019utilisateurs au format JSON.<br \/>\nVous pouvez avoir cette m\u00eame liste au format XML en suffixant l&rsquo;URL avec \u00ab\u00a0.xml\u00a0\u00bb.<br \/>\nEn appelant URL suivante http:\/\/localhost\/symfony-rest\/api\/users\/1, le serveur retournera l\u2019utilisateur d\u00e9fini par l\u2019identifiant 1.<\/p>\n<pre><code class=\"no-highlight\">{\n    \"users\": [\n        {\n            \"id\": 1,\n            \"email\": \"jdoe@domain.com\",\n            \"name\": \"John Doe\",\n            \"password\": \"449bf6759f52bc0d1b7953f9fc2aaf32\"\n        },\n        {\n            \"id\": 2,\n            \"email\": \"jdalton@domain.com\",\n            \"name\": \"Joe Dalton\",\n            \"password\": \"04bd53ec196f6de5101ab3a56f12d0a6\"\n        }\n    ]\n}\n<\/code><\/pre>\n<pre><code class=\"no-highlight\">{\n    \"user\": {\n        \"id\": 1,\n        \"email\": \"jdoe@domain.com\",\n        \"name\": \"John Doe\",\n        \"password\": \"449bf6759f52bc0d1b7953f9fc2aaf32\"\n    }\n}\n<\/code><\/pre>\n<p>Par d\u00e9faut l\u2019API retourne tous les champs de notre entity. Vous avez la possibilit\u00e9 de pr\u00e9ciser soit par inclusion, soit par exclusion, les champs que vous souhaitez envoyer.<br \/>\nExemple dans notre cas en excluant le champ password :<\/p>\n<pre><code class=\"php\">namespace AppBundle\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\nuse JMS\\Serializer\\Annotation\\ExclusionPolicy;\nuse JMS\\Serializer\\Annotation\\Exclude;\nuse Doctrine\\Common\\Collections\\ArrayCollection;\n\n\/**\n * User\n *\n * @ORM\\Table(name=\"User\")\n * @ORM\\Entity(repositoryClass=\"AppBundle\\Repository\\UserRepository\")\n * @ExclusionPolicy(\"none\")\n *\/\nclass User\n{\n    \/**\n     * @var int\n     *\n     * @ORM\\Column(name=\"id\", type=\"integer\")\n     * @ORM\\Id\n     * @ORM\\GeneratedValue(strategy=\"AUTO\")\n     *\/\n    private $id;\n\n    \/**\n     * @var string\n     *\n     * @ORM\\Column(name=\"name\")\n     *\/\n    private $name;\n\n    \/**\n     * @var string\n     *\n     * @ORM\\Column(name=\"email\")\n     *\/\n    private $email;\n\n    \/**\n     * @var string\n     *\n     * @ORM\\Column(name=\"password\")\n     * @Exclude\n     *\/\n    private $password;\n\n    \/\/......\n<\/code><\/pre>\n<p>Il nous reste maintenant \u00e0 mettre \u00e0 disposition une documentation pour les personnes qui voudraient \u00e9ventuellement utiliser notre API.<\/p>\n<p>Pour cela nous allons utiliser le bundle <strong>NelmioApiDocBundle <\/strong>qui se base sur l\u2019outil <a href=\"http:\/\/swagger.io\/\" target=\"_blank\" rel=\"noopener\">Swagger<\/a> pour g\u00e9n\u00e9rer une documentation pratique et lisible.<br \/>\nDe notre c\u00f4t\u00e9, il faudra renseigner les informations utiles \u00e0 la documentation dans le <em>PHPDoc<\/em> de chaque fonction de nos controllers.<\/p>\n<p>Dans un premier temps il faut ajouter le bundle \u00e0 notre configuration et le param\u00e9trer.<\/p>\n<pre><code class=\"no-highlight\">composer require nelmio\/api-doc-bundle\n<\/code><\/pre>\n<p>On l&rsquo;ajoute au fichier <code>app\/AppKernel.php<\/code><\/p>\n<pre><code class=\"php\">new NelmioApiDocBundleNelmioApiDocBundle(),\n<\/code><\/pre>\n<p>Petite ligne de configuration dans le fichier <code>app\/config\/config.yml<\/code><\/p>\n<pre><code class=\"yaml\">nelmio_api_doc: ~\n<\/code><\/pre>\n<p>Et enfin le routing qui va bien : <code>app\/config\/routing.yml<\/code><\/p>\n<pre><code class=\"yaml\">NelmioApiDocBundle:\n    resource: \"@NelmioApiDocBundle\/Resources\/config\/routing.yml\"\n    prefix:   \/api\/doc\n<\/code><\/pre>\n<p>Voici maintenant \u00e0 quoi ressemble le PHPDoc de nos fonctions dans <code>UsersController.php<\/code>.<\/p>\n<pre><code class=\"php\">namespace AppBundle\\Controller;\n\nuse AppBundle\\Entity\\User;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller;\nuse Nelmio\\ApiDocBundle\\Annotation\\ApiDoc;\n\nclass UsersController extends Controller\n{\n    \/**\n     * Cette fonction retourne tous les utilisateurs\n     * Possibilit\u00e9 de d\u00e9crire la fonction plus en d\u00e9tails\n     *\n     * @ApiDoc(\n     *  resource=true,\n     *  description=\"Retourne les utilisateurs\"\n     * )\n     *\n     * @return array\n     *\/\n    public function getUsersAction()\n    {\n        $em = $this-&gt;getDoctrine()-&gt;getManager();\n        $users = $em-&gt;getRepository('AppBundle:User')-&gt;findAll();\n\n        return array('users' =&gt; $users);\n    }\n\n    \/**\n     * Cette fonction retourne un utilisateur\n     * Possibilit\u00e9 de d\u00e9crire la fonction plus en d\u00e9tails\n     *\n     * @ApiDoc(\n     *  description=\"Retourne un utilisateur\",\n     *  parameters={\n     *      {\"name\"=\"id\", \"dataType\"=\"integer\", \"required\"=true, \"description\"=\"identifiant de l'utilisateur\"}\n     *  }\n     * )\n     *\n     * @param User $user\n     * @return array\n     *\/\n    public function getUserAction(User $user)\n    {\n        return array('user' =&gt; $user);\n    }\n}\n<\/code><\/pre>\n<p>Pour cr\u00e9er des fonctionnalit\u00e9s POST\/DELETE\/PUT, qui sont les <em>verbes<\/em> qui caract\u00e9risent une application RESTful, il suffit de pr\u00e9fixer le nom de votre fonction comme ceci : postUserAction(), putUserAction() etc.<\/p>\n<p>D\u00e9sormais, vous pouvez partager la documentation de votre API \u00e0 cette adresse http:\/\/localhost\/symfony-rest\/api\/doc.<\/p>\n<p>Voici \u00e0 quoi ressemble le rendu final :<\/p>\n<p><a href=\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2016\/04\/swagger.png\" rel=\"attachment wp-att-559\" data-rel=\"lightbox-gallery-UCcs8jjY\" data-rl_title=\"\" data-rl_caption=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-559 size-medium\" title=\"\" src=\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2016\/04\/swagger-300x130.png\" alt=\"Documentation API avec Swagger\" width=\"300\" height=\"130\" srcset=\"https:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2016\/04\/swagger-300x130.png 300w, https:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2016\/04\/swagger-768x332.png 768w, https:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2016\/04\/swagger-1024x443.png 1024w, https:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2016\/04\/swagger.png 1902w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Une \u00e9tape suppl\u00e9mentaire sera de g\u00e9rer une identification utilisateur s\u00e9curis\u00e9e via OAuth2.<br \/>\nPeut-\u00eatre dans un prochain billet :)<\/p>\n<div style=\"padding-bottom:20px; padding-top:10px;\" class=\"hupso-share-buttons\"><!-- Hupso Share Buttons - https:\/\/www.hupso.com\/share\/ --><a class=\"hupso_counters\" href=\"https:\/\/www.hupso.com\/share\/\"><img decoding=\"async\" src=\"https:\/\/static.hupso.com\/share\/buttons\/dot.png\" style=\"border:0px; padding-top:2px; float:left;\" alt=\"Share Button\"\/><\/a><script type=\"text\/javascript\">var hupso_services_c=new Array(\"twitter\",\"facebook_like\",\"pinterest\",\"email\",\"linkedin\");var hupso_counters_lang = \"en_US\";var hupso_image_folder_url = \"\";var hupso_url_c=\"\";var hupso_title_c=\"D%C3%A9velopper%20une%20API%20REST%20avec%20Symfony%203\";<\/script><script type=\"text\/javascript\" src=\"https:\/\/static.hupso.com\/share\/js\/counters.js\"><\/script><!-- Hupso Share Buttons --><\/div>","protected":false},"excerpt":{"rendered":"<p>Symfony (2 et 3) permet de publier tr\u00e8s facilement une API REST \u00e0 l\u2019aide de diff\u00e9rents bundles. Cette API peut \u00eatre \u00e9galement fourni d\u2019une documentation g\u00e9n\u00e9r\u00e9e dynamiquement. L\u2019id\u00e9e est de cr\u00e9er une API REST simple, qui met \u00e0 disposition une liste d\u2019utilisateurs et de commentaires. Commen\u00e7ons par g\u00e9n\u00e9rer un nouveau projet.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[92,2],"tags":[57,29,18],"class_list":["post-557","post","type-post","status-publish","format-standard","hentry","category-api","category-php","tag-php","tag-rest","tag-symfony"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>D\u00e9velopper une API REST avec Symfony 3 - Melting Poutre<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"D\u00e9velopper une API REST avec Symfony 3 - Melting Poutre\" \/>\n<meta property=\"og:description\" content=\"Symfony (2 et 3) permet de publier tr\u00e8s facilement une API REST \u00e0 l\u2019aide de diff\u00e9rents bundles. Cette API peut \u00eatre \u00e9galement fourni d\u2019une documentation g\u00e9n\u00e9r\u00e9e dynamiquement. L\u2019id\u00e9e est de cr\u00e9er une API REST simple, qui met \u00e0 disposition une liste d\u2019utilisateurs et de commentaires. Commen\u00e7ons par g\u00e9n\u00e9rer un nouveau projet.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\" \/>\n<meta property=\"og:site_name\" content=\"Melting Poutre\" \/>\n<meta property=\"article:published_time\" content=\"2016-04-11T18:26:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-03-05T21:23:08+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\" \/>\n<meta name=\"author\" content=\"Louis Hatier\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Louis Hatier\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\"},\"author\":{\"name\":\"Louis Hatier\",\"@id\":\"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11\"},\"headline\":\"D\u00e9velopper une API REST avec Symfony 3\",\"datePublished\":\"2016-04-11T18:26:42+00:00\",\"dateModified\":\"2021-03-05T21:23:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\"},\"wordCount\":476,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11\"},\"image\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\",\"keywords\":[\"PHP\",\"REST\",\"Symfony\"],\"articleSection\":[\"API\",\"PHP\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\",\"url\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\",\"name\":\"D\u00e9velopper une API REST avec Symfony 3 - Melting Poutre\",\"isPartOf\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\",\"datePublished\":\"2016-04-11T18:26:42+00:00\",\"dateModified\":\"2021-03-05T21:23:08+00:00\",\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage\",\"url\":\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\",\"contentUrl\":\"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg\"},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/louis.hatier.me\/blog\/#website\",\"url\":\"https:\/\/louis.hatier.me\/blog\/\",\"name\":\"Melting Poutre\",\"description\":\"Du web et d&#039;autres choses\",\"publisher\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/louis.hatier.me\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11\",\"name\":\"Louis Hatier\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cd8d107ede5a4ec340326655e74a00ca62b02e41a02442f961c36f085aa89942?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cd8d107ede5a4ec340326655e74a00ca62b02e41a02442f961c36f085aa89942?s=96&d=mm&r=g\",\"caption\":\"Louis Hatier\"},\"logo\":{\"@id\":\"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/louis.hatier.me\",\"https:\/\/www.linkedin.com\/in\/louishatier\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"D\u00e9velopper une API REST avec Symfony 3 - Melting Poutre","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/","og_locale":"fr_FR","og_type":"article","og_title":"D\u00e9velopper une API REST avec Symfony 3 - Melting Poutre","og_description":"Symfony (2 et 3) permet de publier tr\u00e8s facilement une API REST \u00e0 l\u2019aide de diff\u00e9rents bundles. Cette API peut \u00eatre \u00e9galement fourni d\u2019une documentation g\u00e9n\u00e9r\u00e9e dynamiquement. L\u2019id\u00e9e est de cr\u00e9er une API REST simple, qui met \u00e0 disposition une liste d\u2019utilisateurs et de commentaires. Commen\u00e7ons par g\u00e9n\u00e9rer un nouveau projet.","og_url":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/","og_site_name":"Melting Poutre","article_published_time":"2016-04-11T18:26:42+00:00","article_modified_time":"2021-03-05T21:23:08+00:00","og_image":[{"url":"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg","type":"","width":"","height":""}],"author":"Louis Hatier","twitter_misc":{"\u00c9crit par":"Louis Hatier","Dur\u00e9e de lecture estim\u00e9e":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#article","isPartOf":{"@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/"},"author":{"name":"Louis Hatier","@id":"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11"},"headline":"D\u00e9velopper une API REST avec Symfony 3","datePublished":"2016-04-11T18:26:42+00:00","dateModified":"2021-03-05T21:23:08+00:00","mainEntityOfPage":{"@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/"},"wordCount":476,"commentCount":6,"publisher":{"@id":"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11"},"image":{"@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage"},"thumbnailUrl":"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg","keywords":["PHP","REST","Symfony"],"articleSection":["API","PHP"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/","url":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/","name":"D\u00e9velopper une API REST avec Symfony 3 - Melting Poutre","isPartOf":{"@id":"https:\/\/louis.hatier.me\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage"},"image":{"@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage"},"thumbnailUrl":"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg","datePublished":"2016-04-11T18:26:42+00:00","dateModified":"2021-03-05T21:23:08+00:00","inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/louis.hatier.me\/blog\/developper-api-rest-symfony-3\/#primaryimage","url":"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg","contentUrl":"http:\/\/louis.hatier.me\/blog\/wp-content\/uploads\/2015\/08\/logo-symfony.jpg"},{"@type":"WebSite","@id":"https:\/\/louis.hatier.me\/blog\/#website","url":"https:\/\/louis.hatier.me\/blog\/","name":"Melting Poutre","description":"Du web et d&#039;autres choses","publisher":{"@id":"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/louis.hatier.me\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":["Person","Organization"],"@id":"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/2f200d0368def135b452e65491c4dd11","name":"Louis Hatier","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cd8d107ede5a4ec340326655e74a00ca62b02e41a02442f961c36f085aa89942?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cd8d107ede5a4ec340326655e74a00ca62b02e41a02442f961c36f085aa89942?s=96&d=mm&r=g","caption":"Louis Hatier"},"logo":{"@id":"https:\/\/louis.hatier.me\/blog\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/louis.hatier.me","https:\/\/www.linkedin.com\/in\/louishatier\/"]}]}},"_links":{"self":[{"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/posts\/557","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/comments?post=557"}],"version-history":[{"count":13,"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/posts\/557\/revisions"}],"predecessor-version":[{"id":878,"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/posts\/557\/revisions\/878"}],"wp:attachment":[{"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/media?parent=557"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/categories?post=557"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/louis.hatier.me\/blog\/wp-json\/wp\/v2\/tags?post=557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}