{"id":10436,"date":"2014-11-06T00:43:11","date_gmt":"2014-11-05T23:43:11","guid":{"rendered":"http:\/\/flaven.fr\/?p=10436"},"modified":"2026-05-12T19:03:52","modified_gmt":"2026-05-12T17:03:52","slug":"slim-api-framework-les-bonnes-pratiques-pour-creer-une-api-avec-le-micro-framework-php-slim","status":"publish","type":"post","link":"https:\/\/flaven.fr\/2014\/11\/slim-api-framework-les-bonnes-pratiques-pour-creer-une-api-avec-le-micro-framework-php-slim\/","title":{"rendered":"Slim, API, Framework &#8211; Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim"},"content":{"rendered":"<p>  <!--  Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim --><br \/>\n  \t<!--  Slim, API, Framework , Silex, Symfony, ORM, Kohana, JSON, XML, Laravel, Eloquent, Advanced REST client, Google Chrome  --><\/p>\n<p>Il s&#8217;agit de comprendre rapidement comment concevoir puis de coder &#8220;grosses mailles&#8221; une API.<\/p>\n<p>Les objectifs de cette exp\u00e9rience \u00e9taient les suivants : <\/p>\n<ol>\n<li>D\u00e9couvrir les principes et les meilleures pratiques possibles pour concevoir une API.<\/li>\n<li>Choisir un micro framework ou petit framework pour r\u00e9aliser ce prototype d&#8217;API afin d&#8217;avoir un exemple fonctionnel au bout d&#8217;une seule it\u00e9ration.<\/li>\n<li>Appliquer \u00e0 la lettre un principe de la m\u00e9thode &#8220;lean&#8221; : lancer au plus vite une r\u00e9alisation m\u00eame imparfaite dont la fonction premi\u00e8re est de servir de base \u00e0 la discussion et l&#8217;exp\u00e9rimentation en vue que chacun participe \u00e0 son am\u00e9lioration. Une API ne se construit pas seul, elle est le fruit d&#8217;une collaboration afin que l&#8217;API puisse embrasser toutes les complexit\u00e9s du d\u00e9veloppement \u00e0 son usage, en passant par son co\u00fbt.<\/li>\n<\/ol>\n<p>Bien \u00e9videmment, une fois ce prototype d&#8217;API construit, ce premier &#8220;most viable product&#8221; si cher \u00e0 la m\u00e9thode \u00ab\u00a0lean\u00a0\u00bb, l&#8217;API pourrait \u00eatre confi\u00e9e \u00e0 de vrais d\u00e9veloppeurs pour que celle-ci soit d\u00e9velopp\u00e9e \u00e0 nouveau \u00e0 l&#8217;aide d&#8217;un framework plus &#8220;balaise&#8221; comme Symfony, Laravel ou Kohana.<\/p>\n<p><b>Il existe pas mal de ressources pour concevoir une API de production et non un seul prototype comme c&#8217;est le cas dans ce billet. On donne dans cette article que les premi\u00e8res bonnes pratiques &#8220;Restfull&#8221; pour concevoir une API &#8220;restish&#8221; !<\/b><br \/>\n<\/p>\n<h2>1. Guidelines &amp; bonnes pratiques de construction d&#8217;une API<\/h2>\n<h4>1.1 Les m\u00e9thodes HTTP (HTTP Methods)<\/h4>\n<p>Toute bonne API se doit supporter les m\u00e9thodes HTTP les plus couramment utilis\u00e9s (GET, POST, PUT et DELETE)*. Certes, il existes d&#8217;autres m\u00e9thodes tel que OPTIONS ou HEAD mais notre API va se concentrer sur les plus couramment utilis\u00e9s. Chaque m\u00e9thode sera utilis\u00e9e en fonction du type d&#8217;op\u00e9ration qui sera men\u00e9.<\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<br \/>\n[trow]<br \/>\n\t\t[thcol]METHODE[\/thcol]<br \/>\n\t\t[thcol]DESCRIPTION[\/thcol]<br \/>\n[\/trow]<br \/>\n[trow]\t[tcol]GET[\/tcol]<br \/>\n\t\t[tcol]Obtenir une ressource existante[\/tcol]<br \/>\n[\/trow]<br \/>\n[trow]<br \/>\n\t\t[tcol]POST[\/tcol]<br \/>\n\t\t[tcol]Cr\u00e9er une nouvelle ressource[\/tcol]<br \/>\n[\/trow]<br \/>\n[trow]<br \/>\n\t\t[tcol]PUT[\/tcol]<br \/>\n\t\t[tcol]Mettre \u00e0 jour une ressource existante[\/tcol]<br \/>\n[\/trow]<br \/>\n[trow]<br \/>\n\t\t[tcol]DELETE[\/tcol]<br \/>\n\t\t[tcol]Supprimer une ressource existante[\/tcol]<br \/>\n[\/trow]<br \/>\n[\/table]<\/p>\n<p><i>*Ces diff\u00e9rentes op\u00e9rations sont aussi connus sous l&#8217;acronyme CRUD (Create, Retrieve, Use, Delete)<\/i><br \/>\n<\/p>\n<h4>1.2 HTTP Status Code ou connaitre les codes<\/H4><br \/>\nLes diff\u00e9rents statuts de codes HTTP permettent d&#8217;informer quelle action doit \u00eatre accomplie par l&#8217;application cliente. Fournir au plus vite un statut est du point de l&#8217;utilisation des serveurs, beaucoup plus efficient donc forc\u00e9ment \u00e9conomique en effet la r\u00e9ponse est imm\u00e9diate, on indique donc au client (app, browser&#8230;) de ne pas chercher plus loin.<br \/>\n<\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<br \/>\n\t[trow]<br \/>\n\t\t[thcol]STATUT[\/thcol]<br \/>\n\t\t[thcol]DESCRIPTION[\/thcol]<br \/>\n\t[\/trow]<br \/>\n[trow]<br \/>\n\t[tcol]200[\/tcol]<br \/>\n\t\t[tcol]OK[\/tcol]<br \/>\n[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]201[\/tcol]<br \/>\n\t\t[tcol]Created[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]304[\/tcol]<br \/>\n\t\t[tcol]Not Modified[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]400[\/tcol]<br \/>\n\t\t[tcol]Bad Request[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]401[\/tcol]<br \/>\n\t\t[tcol]Unauthorized[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]403[\/tcol]<br \/>\n\t\t[tcol]Forbidden[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]404[\/tcol]<br \/>\n\t\t[tcol]Not Found[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]422[\/tcol]<br \/>\n\t\t[tcol]Unprocessable Entity[\/tcol]<br \/>\n\t[\/trow]<br \/>\n\t[trow]<br \/>\n\t\t[tcol]500[\/tcol]<br \/>\n\t\t[tcol]Internal Server Error[\/tcol]<br \/>\n\t[\/trow]<br \/>\n[\/table]<br \/>\n<\/p>\n<h4>1.3 URL Structure, une structure d&#8217;URL explicite<\/h4>\n<p>Dans la conception d&#8217;une API REST, les extr\u00e9mit\u00e9s des URL (endpoints) doivent \u00eatre explicites et faciles \u00e0 comprendre.<\/p>\n<p>L&#8217;URL d&#8217;acc\u00e8s \u00e0 chaque ressource doit \u00eatre trivial et \u00eatre identifi\u00e9 de mani\u00e8re unique.<\/p>\n<p>Si l&#8217;API n\u00e9cessite une cl\u00e9 afin d&#8217;acc\u00e9der aux ressources, cette cl\u00e9 doit \u00eatre stock\u00e9e dans les headers HTTP et non dans l&#8217;URL.<\/p>\n<p><b>Exemples :<\/b><\/p>\n<ul>\n<li>GET http:\/\/api.mondomaine.com\/v1\/projects\/id\/16 &#8211; Donne tous les d\u00e9tails du projet dont l&#8217;ID est 16.<\/li>\n<li>POST http:\/\/api.smondomaine.com\/v1\/projects\/new \u2013 Cr\u00e9er un nouveau projet<\/li>\n<\/ul>\n<h4>1.4 API Versioning ou l&#8217;\u00e9pineuse question de la version<\/h4>\n<p>Il existe un d\u00e9bat sans fin sur o\u00f9 indiquer la version de l&#8217;application dans l&#8217;URL ou les en-t\u00eates HTTP. M\u00eame si la recommandation qui pr\u00e9vaut est de faire figurer la version dans l&#8217;en-t\u00eate, on choisit \u00e0 la mani\u00e8re de Twitter, de faire figurer la version dans l&#8217;URL, cela indique plus facilement \u00e0 l&#8217;utilisateur la version sur laquelle et se r\u00e9v\u00e8le bien plus commode lors d&#8217;une migration.<\/p>\n<p>Apr\u00e8s tout, une API est l\u00e0 pour exposer l&#8217;intelligence et le contenu de votre application aux utilisateurs alors autant faciliter la dialogue et la compr\u00e9hension.<\/p>\n<p><b>Exemples :<\/b><\/p>\n<ul>\n<li>http:\/\/api.mondomaine.com\/v1.0\/projects &#8211; version 1.0<\/li>\n<li>http:\/\/api.mondomaine.com\/v1.2\/projects &#8211; version 1.2<\/li>\n<li>http:\/\/api.mondomaine.com\/v2.0\/projects &#8211; version 2.0<\/li>\n<\/ul>\n<p><H4>1.5 Content Type, quel type de contenu<\/H4><br \/>\nLe &#8220;Content-Type&#8221; dans l&#8217;en-t\u00eate HTTP pr\u00e9cise le type de donn\u00e9es contenu qui est \u00e9chang\u00e9 entre le serveur et le client. Afin d&#8217;\u00eatre totalement transparent, le terme &#8220;client&#8221; d\u00e9signe parfois une r\u00e9alit\u00e9 diff\u00e9rente, cela peut-\u00eatre un navigateur, une app iOS ou Android voir une autre API&#8230;<\/p>\n<p>Les principaux format ou type de contenu que supporte habituellement les API Rest sont :<\/p>\n<ul>\n<li>Le JSON ex Mime Content-Type: application\/json<\/li>\n<li>Le XML ex Content-Type: application\/xml<\/li>\n<\/ul>\n<p>Il existe bien sur d&#8217;autre formats ou type de contenu<\/p>\n<p>Source : <a href=\"http:\/\/en.wikipedia.org\/wiki\/MIME_type\" target=\"_blank\">http:\/\/en.wikipedia.org\/wiki\/MIME_type<\/a><\/p>\n<p><H4>1.6 API Key, la cl\u00e9 du bonheur<\/H4><br \/>\nIl est \u00e9vident que l&#8217;on construit g\u00e9n\u00e9ralement une API publique afin de facilit\u00e9 l&#8217;adoption et d&#8217;exposer des contenus. Toutefois, m\u00eame sur un mode gratuit, l&#8217;usage doit \u00eatre contr\u00f4l\u00e9 voir limit\u00e9 en volume et possibilit\u00e9 pour des raisons de s\u00e9curit\u00e9 et\/ou de co\u00fbt.<\/p>\n<p>En effet, exploiter une API co\u00fbte des ressources et c&#8217;est aussi un des socles de la mon\u00e9tisation d&#8217;un SaaS, il faut donc pr\u00e9voir de r\u00e9duire ou de limiter l&#8217;acc\u00e8s \u00e0 cette ressource via une cl\u00e9 d&#8217;API.<\/p>\n<p>C&#8217;est une \u00e9volution importante concernant la gestion d&#8217;une API. En effet si l&#8217;on pense mon\u00e9tisation, il faudra de facto faire \u00e9voluer le compte utilisateur \u00e0 l&#8217;instar d&#8217;un Facebook ou Twitter. Dans un monde parfait, l&#8217;utilisateur g\u00e8re lui-m\u00eame ses apps, il d\u00e9clare son\/ses application(s), mets une description, obtient une cl\u00e9 d&#8217;API, un token client priv\u00e9&#8230; bref toutes les informations n\u00e9cessaires \u00e0 la gestion d&#8217;une application adoss\u00e9e \u00e0 une API. Tout cela est d\u00e9l\u00e9gu\u00e9 \u00e0 l&#8217;utilisateur, c&#8217;est le cercle vertueux pour une API, vous d\u00e9l\u00e9guer la gestion client \u00e0 vos utilisateurs ainsi que tout ce qui concerne le param\u00e9trage.<\/p>\n<h2>2. Cr\u00e9er une REST API _ User stories<\/h2>\n<h4>2.1 L\u00e2cher le silex pour le slim<\/h4>\n<p>Cretes, notre choix aurait ou se porter sur <code>Silex<\/code> qui est une \u00e9manation &#8220;light&#8221; de <b>Symfony<\/b> mais bon, le choix s&#8217;est port\u00e9 sur Slim. En effet, quelques-unes des ressources (tutorial, vid\u00e9o notamment&#8230;) cadraient parfaitement avec le volont\u00e9 affich\u00e9e de cette exp\u00e9rience d&#8217;apprentissage : choisir un de ces micro framework PHP facile \u00e0 mettre en place et \u00e0 man\u0153uvrer. <\/p>\n<p><b>En conclusion, on aurait pu choisir Silex mais les recherches sur internet ont permis de d\u00e9couvrir une suite de 10 vid\u00e9os qui expliquent pas \u00e0 pas l&#8217;utilisation de Slim.<\/b><\/p>\n<ol>\n<li>Les videos d&#8217;Eduardo Diaz sur la maniement de Slim (spanish)<br \/><a href=\"http:\/\/www.youtube.com\/user\/alexdx\/videos\" target=\"_blank\">http:\/\/www.youtube.com\/user\/alexdx\/videos<\/a><\/li>\n<\/ol>\n<h4>2.2 Agile ?<\/h4>\n<p>Afin de se figurer comment concevoir l&#8217;API, le mieux est de d\u00e9crire via des user stories ou des histoires utilisateurs l&#8217;usage que nous souhaitons faire de notre API.<\/p>\n<h5>(i) Simple User story ou actions habituelles<\/h5>\n<p>Bon les op\u00e9ration dites communes&#8230;<\/p>\n<ul>\n<li>Toutes les op\u00e9rations relatives \u00e0 l&#8217;inscription (registration) et de login<\/li>\n<li>Toutes les op\u00e9rations li\u00e9es \u00e0 la gestion de projets (CRUD, Creating, Reading, Updating, Deleting). Pour toutes ces op\u00e9rations, les appels \u00e0 l&#8217;API doivent inclure une cl\u00e9 d&#8217;API d&#8217;autorisation dans le champ HEAD.<\/li>\n<\/ul>\n<h5>(ii) Advanced User story ou actions sp\u00e9cifiques<\/h5>\n<p>Les op\u00e9rations plus avanc\u00e9es <\/p>\n<ul>\n<li>Lister tous les projets d&#8217;un compte utilisateur soit comme cr\u00e9ateur (case 1) soit comme contributeur (case 2) soit les 2 (case 3).<\/li>\n<li>Lister tous les contributeurs \u00e0 un projet donn\u00e9<\/li>\n<li>Lister tous les mots-cl\u00e9s d&#8217;un projet donn\u00e9.<\/li>\n<\/ul>\n<p><i> &#8230;to be continued<\/i><\/p>\n<p><b>Pour information, les principaux types de Requests sur une API REST :  GET,POST, PUT, PATCH, DELETE, HEAD, OPTIONS.<\/b><\/p>\n<h4>3.3 Nomenclature des URLs : deux \u00e9coles<\/h4>\n<h5>(i) Type 1 : Les URLs sont identiques mais les m\u00e9thodes d&#8217;appel \u00e0 l&#8217;API diff\u00e9rent.<\/h5>\n<p> On peut souvent utiliser la m\u00eame URL pour l&#8217;appel \u00e0 l&#8217;API. Si l&#8217;URL est identique la diff\u00e9rence se fait surtout sur le type de m\u00e9thode HTTP qui est utilis\u00e9 dans l&#8217;une ou l&#8217;autre des URLs.<\/p>\n<p> Imaginons que le client demande l&#8217;URL de l&#8217;API \/projects\/id\/:id d&#8217;un projet sp\u00e9cifique avec la m\u00e9thode GET, le client obtiendra la liste des informations affairantes \u00e0 ce projet. Si par contre le client utilise la m\u00e9thode PUT<\/p>\n<ul>\n<li>\/projects\/id\/:id GET \t-> Liste les infos d&#8217;un projet ayant cet id<\/li>\n<li>\/projects\/id\/:id PUT \t-> Met \u00e0 jour le projet ayant cet id<\/li>\n<li>\/projects\/id\/:id DELETE -> Supprime le projet ayant cet id<\/li>\n<\/ul>\n<h5>(ii) Type 2 : Les URLs sont explicites et donnent un indication m\u00eame sur la m\u00e9thode employ\u00e9.<\/h5>\n<p> Les URLs d&#8217;appel figurent autant que possible l&#8217;usage qui est fait. Personnellement c&#8217;est ce que je pr\u00e9f\u00e8re, sortir de ce qui est implicite pour avoir de l&#8217;explicite. En effet, l&#8217;API peut-\u00eatre test\u00e9e et\/ou utilis\u00e9e par des personnes qui ignorent tous des conventions &#8220;techniques&#8221; et une simple lecture de la documentation de l&#8217;API suffit \u00e0 convaincre que des nombreuses op\u00e9rations sont possibles.<\/p>\n<ul>\n<li>\/projects\/id\/:id GET \t-> Liste les infos d&#8217;un projet ayant cet id<\/li>\n<li>\/projects\/update\/:id PUT \t-> Met \u00e0 jour le projet ayant cet id<\/li>\n<li>\/projects\/delete\/:id DELETE -> Supprime le projet ayant cet id<\/li>\n<\/ul>\n<h5>(iii) Tableau des structures Url de l&#8217;API + m\u00e9thode<\/h5>\n<p> On a appliqu\u00e9 la nomenclature de Type 2. Pour m\u00e9moire, on d\u00e9compose \u00e0 nouveau une URL compl\u00e8te d&#8217;appel http:\/\/api.mondomaine.com\/v2.0\/projects\/all.<\/p>\n<ul>\n<li>url_part_1 : http:\/\/api.mondomaine.com -> C&#8217;est l&#8217;URL de base, simple et facile \u00e0 retenir.<\/li>\n<li>url_part_2 : \/v2.0 -> C&#8217;est la partie qui indique la version de l&#8217;API \u00e0 laquelle on fait l&#8217;appel.<\/li>\n<li>url_part_3 : \/projects\/all -> C&#8217;est la partie d&#8217;interaction avec l&#8217;API dans l&#8217;URL d&#8217;appel.<\/li>\n<\/ul>\n<p> Ce qui donne le tableau suivant pour les combinaisons de la part_3<\/p>\n<p><b>(A) User management<\/b><\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<\/p>\n<p>\t\t\t[trow]<br \/>\n\t\t\t\t[thcol]URL[\/thcol]<br \/>\n\t\t\t\t[thcol]Method[\/thcol]<br \/>\n\t\t\t\t[thcol]Parameters[\/thcol]<br \/>\n\t\t\t\t[thcol]Description[\/thcol]<br \/>\n\t\t\t\t[\/trow]<\/p>\n<p>\t\t\t [trow]<br \/>\n\t\t\t \t[tcol]\/register[\/tcol]<br \/>\n\t\t\t \t[tcol]POST[\/tcol]<br \/>\n\t\t\t \t[tcol]mail, password[\/tcol]<br \/>\n\t\t\t \t[tcol]User registration[\/tcol]<br \/>\n\t\t\t [\/trow]<\/p>\n<p>\t\t\t [trow]<br \/>\n\t\t\t \t[tcol]\/login[\/tcol]<br \/>\n\t\t\t\t[tcol]POST[\/tcol]<br \/>\n\t\t\t\t[tcol]mail, password[\/tcol]<br \/>\n\t\t\t\t[tcol]User login[\/tcol]<br \/>\n\t\t\t[\/trow]<br \/>\n[\/table]<\/p>\n<p><b>(B) Project management<\/b><br \/>\n[table type=&#8221;standard_bordered&#8221;]<\/p>\n<p>[trow]<br \/>\n [tcol]\/projects\/all[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching all projects[\/tcol]<br \/>\n[\/trow] <\/p>\n<p> [trow]<br \/>\n [tcol]\/projects\/new[\/tcol]<br \/>\n [tcol]POST[\/tcol]<br \/>\n [tcol]project[\/tcol]<br \/>\n [tcol]To create new project[\/tcol]<br \/>\n [\/trow] <\/p>\n<p> [trow]<br \/>\n [tcol]\/projects\/id\/:id[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching single project[\/tcol]<br \/>\n [\/trow] <\/p>\n<p> [trow]<br \/>\n [tcol]\/projects\/update\/:id[\/tcol]<br \/>\n [tcol]PUT[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Updating single project[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/projects\/delete\/:id[\/tcol]<br \/>\n [tcol]DELETE[\/tcol]<br \/>\n [tcol]project, status[\/tcol]<br \/>\n [tcol]Deleting single project[\/tcol]<br \/>\n[\/trow]<br \/>\n[\/table]<\/p>\n<p><b>(C) Tag management<\/b><\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<br \/>\n[trow]<br \/>\n [tcol]\/tags\/all[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching all tags[\/tcol]<br \/>\n [\/trow] <\/p>\n<p> [trow]<br \/>\n [tcol]\/tags\/new[\/tcol]<br \/>\n [tcol]POST[\/tcol]<br \/>\n [tcol]tag[\/tcol]<br \/>\n [tcol]To create new tag or hashtag[\/tcol]<br \/>\n [\/trow] <\/p>\n<p> [trow]<br \/>\n [tcol]\/tags\/id\/:id[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching single tag[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/tags\/update\/:id[\/tcol]<br \/>\n [tcol]PUT[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Updating single tag[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/tags\/delete\/:id[\/tcol]<br \/>\n [tcol]DELETE[\/tcol]<br \/>\n [tcol]tag, status[\/tcol]<br \/>\n [tcol]Deleting single tag[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[\/table]<\/p>\n<p><b>(D) Author management<\/b><\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<\/p>\n<p>[trow]<br \/>\n [tcol]\/authors\/all[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching all authors[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/authors\/new[\/tcol]<br \/>\n [tcol]POST[\/tcol]<br \/>\n [tcol]author[\/tcol]<br \/>\n [tcol]To create new author[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/authors\/id\/:id[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching single author[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/authors\/update\/:id[\/tcol]<br \/>\n [tcol]PUT[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Updating single author[\/tcol]<br \/>\n[\/trow] <\/p>\n<p>[trow]<br \/>\n [tcol]\/authors\/delete\/:id[\/tcol]<br \/>\n [tcol]DELETE[\/tcol]<br \/>\n [tcol]author, status[\/tcol]<br \/>\n [tcol]Deleting single author[\/tcol]<br \/>\n[\/trow]<br \/>\n[\/table]<\/p>\n<p><b>(E) Downloads management<\/b><\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<br \/>\n[trow]<br \/>\n [tcol]\/downloads\/all[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching all downloads[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n [tcol]\/downloads\/id\/:id[\/tcol]<br \/>\n [tcol]GET[\/tcol]<br \/>\n [tcol][\/tcol]<br \/>\n [tcol]Fetching nb of downloads for a single project[\/tcol]<\/p>\n<p> [\/trow]<\/p>\n<p>[\/table]<\/p>\n<p><b>((F) Goodies management<\/b><\/br><br \/>\nQuelques actions juste pour le fun maintenant, il faut voir si elles ne sont pas consommatrices de resources.<\/p>\n<p>[table type=&#8221;standard_bordered&#8221;]<\/p>\n<p>[trow]<\/p>\n<p>\t [tcol]\/projects\/all\/top\/day[\/tcol]<br \/>\n\t [tcol]GET[\/tcol]<br \/>\n\t [tcol]Transverse, Sur une journ\u00e9e, les derniers projets mis \u00e0 jour du plus r\u00e9cent au plus ancien[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n\t[tcol]\/projects\/all\/top\/week[\/tcol]<br \/>\n\t[tcol]GET[\/tcol]<br \/>\n\t[tcol]Idem sur une semaine[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n\t [tcol]\/projects\/all\/top\/month[\/tcol]<br \/>\n\t [tcol]GET\t\t\t\t\t\t[\/tcol]<br \/>\n\t [tcol]Idem sur un mois[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n\t [tcol]\/projects\/all\/top\/year \t\t[\/tcol]<br \/>\n\t [tcol]GET\t\t\t\t\t\t\t\t[\/tcol]<br \/>\n\t [tcol]Idem sur une ann\u00e9e[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n\t[tcol]\/projects\/all\/top\/alltime[\/tcol]<br \/>\n\t[tcol]GET\t\t\t\t\t\t\t[\/tcol]<br \/>\n\t[tcol]Idem depuis que le service existe[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n \t [tcol]\/projects\/id\/:id\/authors\/all\/top\/month[\/tcol]<br \/>\n\t [tcol]GET[\/tcol]<br \/>\n\t [tcol]Par projet, les auteurs les plus actifs du mois sur le projet dont l&#8217;id est :id[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[trow]<br \/>\n\t [tcol]\/authors\/all\/top\/month[\/tcol]<br \/>\n\t [tcol]GET[\/tcol]<br \/>\n\t [tcol]Transverse, les auteurs les plus actifs du mois tous projets confondues[\/tcol]<br \/>\n[\/trow]<\/p>\n<p>[\/table]<\/p>\n<p> L&#8217;id\u00e9e est sans doute de comprendre le fonctionnement et de s&#8217;amuser \u00e0 faire toutes les combinaisons, ensuite voir si cela fait sens et si c&#8217;est techniquement faisable notamment pas chargeant en terme de requ\u00eate ! Cache ?<\/p>\n<h2>3. Cr\u00e9er une REST API _ Ride the ORM<\/h2>\n<p>Pour la construction de l&#8217;API, il faut d&#8217;\u00e9vidence s&#8217;appuyer sur l&#8217;ORM d&#8217;un framework.<\/p>\n<p>Prenons par exemple par Kohana, il existe quelques exemples dans Kohana sur l&#8217;utilisation de l&#8217;ORM, voir \/kohana\/modules\/orm\/guide\/orm\/examples\/ notamment le fichier simple.md<\/p>\n<p><H4>3.1 Notes sur l&#8217;ORM de Kohana<\/H4><\/p>\n<blockquote><p>The ORM allows for manipulation and control of data within a database as though it was a PHP object. Once you define the relationships ORM allows you to pull data from your database, manipulate the data in any way you like, and then save the result back to the database without the use of SQL. By creating relationships between models that follow convention over configuration, much of the repetition of writing queries to create, read, update, and delete information from the database can be reduced or entirely removed. All of the relationships can be handled automatically by the ORM library and you can access related data as standard object properties.<\/p>\n<p>ORM is included with the Kohana 3.x install but needs to be enabled before you can use it. In your `application\/bootstrap.php` file modify the call to Kohana::modules and include the ORM modules.<\/p><\/blockquote>\n<p><b>Bon dans notre exemple, on va utiliser <code>RedBeanPHP<\/code> accessible sans trop de souci via Slim<\/b><\/p>\n<h2>4. Cr\u00e9er une REST API _ Installer Slim<\/h2>\n<p>On va installer \u00e0 l&#8217;aide de composer un ensemble d&#8217;\u00e9l\u00e9ments n\u00e9cessaires au bon fonctionnement de notre application. On a renonc\u00e9 \u00e0 <b>Laravel<\/b> et son ORM <b>Eloquent<\/b>.<\/p>\n<p>Les commandes pour se rendre dans votre r\u00e9pertoire puis installer le tout.<\/p>\n<p><code>cd \/Applications\/MAMP\/htdocs\/slim\/slim_test_api\/<\/code><br \/>\n<code>composer install<\/code><br \/>\n<b>Le contenu de <code>composer.json<\/code> avec slim et RedBeanPHP<\/b><\/p>\n<pre lang=\"bash\">\r\n\t{\r\n\t    \"require\": {\r\n\t        \"slim\/slim\": \"2.*\",\r\n\t\t\t\"gabordemooij\/redbean\": \"*\"\r\n\t\t\r\n\t    }\r\n\t}\r\n<\/pre>\n<p><b>Lancer le composer <code>composer install<\/code><\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_composer_1.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>C&#8217;est fait, vous avez slim et redbean dans un r\u00e9pertoire vendor<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_composer_2.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Confirmation <code>ls -l<\/code><\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_composer_3.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Confirmation <code>ls -la<\/code> pour voir le <code>.htaccess<\/code><\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_composer_4.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Le code de <code>.htaccess<\/code><\/b><\/p>\n<pre lang=\"text\">\r\n\tRewriteEngine On\r\n\tRewriteCond %{REQUEST_FILENAME} !-f\r\n\tRewriteRule ^ index.php [QSA,L]\r\n<\/pre>\n<h2>5. Utiliser notre API _ Quelques exemples&#8230;<\/h2>\n<p>Pour jouer avec notre prototype d&#8217;API, on va utiliser l&#8217;application de Chrome nomm\u00e9 &#8220;Advanced REST client&#8221; afin de passer quelques commandes, du m\u00eame on indique aussi le moyen de passer la m\u00eame commande \u00e0 l&#8217;aide de cURL.<\/p>\n<p><b>Dans Chrome, une application nomm\u00e9e &#8220;Advanced REST client&#8221;<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_advanced_rest_client_application.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><i>Source : <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/advanced-rest-client\/hgmloofddffdnphfgcellkdfbfbjeloo\" target=\"_blank\">Advanced REST client de Google Chrome<\/a><\/i><\/p>\n<h4>5.1 Voir les utilisateurs de la BDD<\/h4>\n<p><b>En cURL<\/b><\/p>\n<pre>curl -i -X GET http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/all<\/pre>\n<pre>curl -i -X GET http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/id\/4<\/pre>\n<h4>5.2 Ajouter des utilisateurs<\/h4>\n<pre>http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/new<\/pre>\n<pre>\r\n{\"nombre\": \"Barack\",\"apellidos\":\"Obama\",\"email\":\"bo@whitehouse.gov\"}\r\n{\"nombre\": \"Michelle\",\"apellidos\":\"Obama\",\"email\":\"mo@whitehouse.gov\"}\r\n{\"nombre\": \"John\",\"apellidos\":\"Smith\",\"email\":\"mdoe@whitehouse.gov\"}\r\n<\/pre>\n<pre>curl -i -X POST -H 'Content-Type: application\/json' -d '{\"nombre\": \"Damian\",\"apellidos\":\"Winograd\",\"email\":\"dwg@whitehouse.gov\"}' http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/new<\/pre>\n<p><b>Ajouter un utilisateur via Advanced REST client de Google Chrome<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_add_user_1.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Bien ajouter application\/json<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_add_user_2.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Le message de notre api en espagnol<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_add_user_3.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Ajouter un utilisateur en cURL<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_add_user_curl.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Vue utilisateur unique ID 4<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_view_user_1.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b><b>Vue tous les utilisateurs<\/b><\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_view_user_all.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b><b>Vue tous les utilisateurs via cURL<\/b><\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_view_user_curl.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<h4>5.3 Supprimer des utilisateurs<\/h4>\n<pre>http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/delete\/13<\/pre>\n<pre>curl -i -X DELETE http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/delete\/13<\/pre>\n<p><b>Supprimer un utilisateur via Advanced REST client de Google Chrome<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_delete_user.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Supprimer un utilisateur en cURL<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_delete_user_curl.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<p><b>Le dump <code>.sql<\/code> de la base via phpmyadmin<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_show_db.jpg\" width=\"500\" height=\"313\" alt=\"Slim, API, Framework - Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim\"><\/p>\n<pre lang=\"sql\">\r\n\t-- phpMyAdmin SQL Dump\r\n\t-- version 4.2.5\r\n\t-- http:\/\/www.phpmyadmin.net\r\n\r\n\tSET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\r\n\tSET time_zone = \"+00:00\";\r\n\r\n\t--\r\n\t-- Base de donn\u00e9es :  `slim`\r\n\t--\r\n\r\n\t-- --------------------------------------------------------\r\n\r\n\t--\r\n\t-- Structure de la table `usuarios`\r\n\t--\r\n\r\n\tCREATE TABLE `usuarios` (\r\n\t`id` int(9) NOT NULL,\r\n\t  `nombre` varchar(50) NOT NULL DEFAULT '',\r\n\t  `apellidos` varchar(100) NOT NULL DEFAULT '',\r\n\t  `email` varchar(255) NOT NULL DEFAULT '',\r\n\t  `alta` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP\r\n\t) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=14 ;\r\n\r\n\t--\r\n\t-- Contenu de la table `usuarios`\r\n\t--\r\n\r\n\tINSERT INTO `usuarios` (`id`, `nombre`, `apellidos`, `email`, `alta`) VALUES\r\n\t(4, 'Bob', 'Obama', 'bobobama@whitehouse.gouv', '2014-10-31 07:37:35'),\r\n\t(12, 'Damian', 'Winograd', 'dwg@whitehouse.gov', '2014-11-03 04:34:41'),\r\n\t(7, 'Ramon', 'Castro', 'ramonc@hotmail.com', '2014-10-31 08:23:43'),\r\n\t(9, 'Barack', 'Obama', 'bo@whitehouse.gov', '2014-11-03 04:15:22'),\r\n\t(10, 'Michelle', 'Obama', 'mo@whitehouse.gov', '2014-11-03 04:15:41');\r\n\r\n\t--\r\n\t-- Index pour les tables export\u00e9es\r\n\t--\r\n\r\n\t--\r\n\t-- Index pour la table `usuarios`\r\n\t--\r\n\tALTER TABLE `usuarios`\r\n\t ADD PRIMARY KEY (`id`);\r\n<\/pre>\n<h2>6. Utiliser notre API _ le code<\/h2>\n<p><b>Le fichier <code>index.php<\/code> de notre prototype de API<\/b><\/p>\n<pre lang=\"php\" escaped=\"true\">\r\n\t&lt;?php\r\n\t\/**\r\n\t * Slim - a micro PHP 5 framework\r\n\t *\r\n\t*\/\r\n\r\n\t\t\trequire 'vendor\/autoload.php';\r\n\t\t\tuse RedBean_Facade as R;\r\n\t\t\r\n\t\t\t$db_host = &quot;localhost&quot;;\r\n\t\t\t$db_dbname = &quot;slim&quot;;\r\n\t\t\t\/\/ $db_dbname = &quot;all_traductions&quot;;\r\n\t\t\t$db_username = &quot;root&quot;;\r\n\t        $db_password = &quot;root&quot;;\r\n\t\t\r\n\t\t\r\n\t\t\tR::setup ('mysql:host='.$db_host.';dbname='.$db_dbname.';chartset=utf8',''.$db_username.'',''.$db_password.'');\r\n\t\t\r\n\t\t\tR::freeze(true);\r\n\r\n\t\t\t$app = new \\Slim\\Slim();\r\n\t\t\t$app->config(array(\r\n\t\t\t    'debug' => true\r\n\t\t\t));\r\n\r\n\t\t\t$app->get('\/', function () use($app) {\r\n\t\t\t\techo ('&lt;h1&gt;Hello to redbean ($app)&lt;\/h1&gt;');\r\n\t\t\t});\r\n\t\t\r\n\t\t\t\/* ALL *\/\r\n\t\t\t\/\/ http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/all\r\n\t\t\t$app->group('\/api', function () use ($app){\r\n\t\t\t\t\t$app->group('\/usuarios', function () use ($app){\r\n\t\t\t\t\t\t$app->response->headers->set('Content-Type', 'application\/json');\r\n\r\n\t\t\t\t\t\t\t$app->get('\/all', function () use($app) {\r\n\t\t\t\t\t\t\t\t$all = R::find('usuarios');\r\n\t\t\t\t\t\t\t\t$all_users = R::exportAll($all);\r\n\t\t\t\t\t\t\t\techo json_encode($all_users);\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\/* LOOK for an ID *\/\r\n\t\t\t\t\t\t\t\/\/ http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/id\/1\r\n\t\t\t\t\t\t\t$app->get('\/id\/:id', function ($id) use($app) {\r\n\t\t\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\t\t\t\/\/all infos about the user based on the id\r\n\t\t\t\t\t\t\t\t\t$usuario = R::load('usuarios', $id);\r\n\t\t\t\t\t\t\t\t\tif ($usuario->id) {\r\n\t\t\t\t\t\t\t\t\t\t$user = $usuario->export();\r\n\t\t\t\t\t\t\t\t\t\techo json_encode($user);\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tthrow new Exception('User does not exist');\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}catch (Exception $e) {\r\n\t\t\t\t\t\t\t\t\t$app->status(400);\r\n\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'error', 'message' => $e->getMessage()));\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\/* NEW ID *\/\r\n\t\t\t\t\t\t\t\/\/ http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/new\r\n\t\t\t\t\t\t\t$app->post('\/new', function () use($app) {\r\n\t\t\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\t\t\t$request = $app->request();\r\n\t\t\t\t\t\t\t\t\t$data = json_decode ($request->getBody());\r\n\t\t\t\t\t\t\t\t\t$usuario = R::dispense('usuarios');\r\n\t\t\t\t\t\t\t\t\t$usuario->nombre = $data->nombre;\r\n\t\t\t\t\t\t\t\t\t$usuario->apellidos = $data->apellidos;\r\n\t\t\t\t\t\t\t\t\t$usuario->email = $data->email;\r\n\t\t\t\t\t\t\t\t\t$insertado = R::store($usuario);\r\n\t\t\t\t\t\t\t\t\tif ($insertado) {\r\n\t\t\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'success', 'message' => 'Insertado correctamente'));\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tthrow new Exception('Error while inserting the user');\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}catch (Exception $e) {\r\n\t\t\t\t\t\t\t\t\t$app->status(400);\r\n\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'error', 'message' => $e->getMessage()));\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\/* UPDATE *\/\r\n\t\t\t\t\t\t\t\/\/ http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/update\/2\r\n\t\t\t\t\t\t\t$app->put('\/update\/:id', function ($id) use($app) {\r\n\t\t\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\t\t\t$id = (int)$id;\r\n\t\t\t\t\t\t\t\t\t$request = $app->request();\r\n\t\t\t\t\t\t\t\t\t$data = json_decode ($request->getBody());\r\n\t\t\t\t\t\t\t\t\t$usuario = R::load('usuarios', $id);\r\n\t\t\t\t\t\t\t\t\tif ($usuario->id) {\r\n\t\t\t\t\t\t\t\t\t\t\/\/Actulizamos datos del usuario\r\n\t\t\t\t\t\t\t\t\t\t$usuario->nombre = $data->nombre;\r\n\t\t\t\t\t\t\t\t\t\t$usuario->apellidos = $data->apellidos;\r\n\t\t\t\t\t\t\t\t\t\t$usuario->email = $data->email;\t\r\n\t\t\t\t\t\t\t\t\t\tR::store($usuario);\r\n\t\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'success', 'message' => 'Actualizado correctamente'));\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tthrow new Exception('Error while updating the user');\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}catch (Exception $e) {\r\n\t\t\t\t\t\t\t\t\t$app->status(400);\r\n\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'error', 'message' => $e->getMessage()));\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\/* DELETE *\/\r\n\t\t\t\t\t\t\t\/\/ http:\/\/127.0.0.1\/slim\/slim_test_api_redbean\/index.php\/api\/usuarios\/delete\/8\r\n\t\t\t\t\t\t\t$app->delete('\/delete\/:id', function ($id) use($app) {\r\n\t\t\t\t\t\t\t\t$id = (int)$id;\r\n\t\t\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\t\t\t\/\/ Buscamos y borramos\r\n\t \t\t\t\t\t\t\t\t$usuario = R::load('usuarios', $id);\r\n\t\t\t\t\t\t\t\t\tif ($usuario->id) {\r\n\t\t\t\t\t\t\t\t\t\tR::trash($usuario);\r\n\t\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'success', 'message' => 'Borrado correctamente'));\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tthrow new Exception('Error while deleting the user');\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}catch (Exception $e) {\r\n\t\t\t\t\t\t\t\t\t$app->status(400);\r\n\t\t\t\t\t\t\t\t\techo json_encode(array('status' => 'error', 'message' => $e->getMessage()));\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\r\n\t\t\t$app->run();\r\n\t\r\n\t\r\n<\/pre>\n<h2>En savoir plus<\/h2>\n<ul>\n<li>Les videos d&#8217;Eduardo Diaz sur la maniement de Slim (spanish)<br \/><a href=\"http:\/\/www.youtube.com\/user\/alexdx\/videos\" target=\"_blank\">http:\/\/www.youtube.com\/user\/alexdx\/videos<\/a><\/li>\n<li>Learn REST: A RESTful Tutorial<br \/><a href=\"http:\/\/www.restapitutorial.com\/\" target=\"_blank\">http:\/\/www.restapitutorial.com\/<\/a><\/li>\n<li>Un excellent framework PHP, Laravel notamment avec son ORM Eloquent<br \/><a href=\"http:\/\/laravel.com\/\" target=\"_blank\">http:\/\/laravel.com\/<\/a><\/li>\n<li>L&#8217;ORM utilis\u00e9 dans notre demo, RedBeanPHP is an easy-to-use, on-the-fly ORM for PHP<br \/><a href=\"http:\/\/redbeanphp.com\/\" target=\"_blank\">http:\/\/redbeanphp.com\/<\/a><\/li>\n<li>L&#8217;auteur de Build APIs You Won&#8217;t Hate et un tr\u00e8s fin connaisseur de Laravel et des bonnes pratiques<br \/><a href=\"https:\/\/philsturgeon.uk\/\" target=\"_blank\">https:\/\/philsturgeon.uk\/<\/a><\/li>\n<li>Un assortiment d&#8217;excellentes vid\u00e9os sur SLIM(espagnol)<br \/><a href=\"http:\/\/12devsofxmas.co.uk\/2012\/12\/day-4-mixing-and-matching-php-components-with-composer\/\" target=\"_blank\">http:\/\/12devsofxmas.co.uk\/2012\/12\/day-4-mixing-and-matching-php-components-with-composer\/<\/a><\/li>\n<li>How to create REST API for Android app using PHP, Slim and MySQL \u2013 Day 1\/2<br \/><a href=\"http:\/\/www.androidhive.info\/2014\/01\/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-12-2\/\" target=\"_blank\">http:\/\/www.androidhive.info\/2014\/01\/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-12-2\/<\/a><\/li>\n<li>How to create REST API for Android app using PHP, Slim and MySQL \u2013 Day 2\/2<br \/><a href=\"http:\/\/www.androidhive.info\/2014\/01\/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-23\/\" target=\"_blank\">http:\/\/www.androidhive.info\/2014\/01\/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-23\/<\/a><\/li>\n<li>\nCreating a RESTful API with PHP using Slim<br \/><a href=\"http:\/\/www.aljtmedia.com\/blog\/creating-a-restful-api-with-php-using-slim\/\" target=\"_blank\">http:\/\/www.aljtmedia.com\/blog\/creating-a-restful-api-with-php-using-slim\/<\/a><\/li>\n<li>Create REST applications with the Slim micro-framework<br \/><a href=\"http:\/\/www.ibm.com\/developerworks\/library\/x-slim-rest\/\" target=\"_blank\">http:\/\/www.ibm.com\/developerworks\/library\/x-slim-rest\/<\/a><\/li>\n<li>Creating a simple REST application with Silex de DAVID MAKIN (part 1)<br \/><a href=\"http:\/\/sleep-er.co.uk\/blog\/2013\/Creating-a-simple-REST-application-with-Silex\/\" target=\"_blank\">http:\/\/sleep-er.co.uk\/blog\/2013\/Creating-a-simple-REST-application-with-Silex\/<\/a><\/li>\n<li>Creating a simple REST application with Silex de DAVID MAKIN (part 2)<br \/><a href=\"http:\/\/sleep-er.co.uk\/blog\/2014\/Creating-a-simple-REST-application-with-Silex-part2\/\" target=\"_blank\">http:\/\/sleep-er.co.uk\/blog\/2014\/Creating-a-simple-REST-application-with-Silex-part2\/<\/a><\/li>\n<li>Learning PHP development with Silex de Bojan \u017divanovi\u0107<br \/><a href=\"http:\/\/bojanz.wordpress.com\/2013\/11\/11\/learning-php-development-with-silex\/\" target=\"_blank\">http:\/\/bojanz.wordpress.com\/2013\/11\/11\/learning-php-development-with-silex\/<\/a><\/li>\n<li>MusicBox is a portal based on the Silex framework, built for PHP 5.3 and MySQL 5. It tries to demonstrate best practices in today&#8217;s world of development, and has been written as a university project by Bojan Zivanovic and Lana Petkovic.<br \/><a href=\"https:\/\/github.com\/bojanz\/musicbox\" target=\"_blank\">https:\/\/github.com\/bojanz\/musicbox<\/a><\/li>\n<li>The PHP micro-framework<br \/>\nbased on the Symfony2 Components<br \/><a href=\"http:\/\/silex.sensiolabs.org\/documentation\" target=\"_blank\">hhttp:\/\/silex.sensiolabs.org\/documentation<\/a><\/li>\n<li>Scaling a Silex code base<br \/><a href=\"https:\/\/igor.io\/2012\/11\/09\/scaling-silex.html\" target=\"_blank\">https:\/\/igor.io\/2012\/11\/09\/scaling-silex.html<\/a><\/li>\n<li>A First Silex Project<br \/><a href=\"http:\/\/sf.khepin.com\/2011\/04\/a-first-silex-project\/\" target=\"_blank\">http:\/\/sf.khepin.com\/2011\/04\/a-first-silex-project\/<\/a><\/li>\n<li>Building APIs with Silex by Cal Evans of Blue Parabola<br \/><a href=\"http:\/\/www.youtube.com\/watch?v=bqxxI_pwcXA\" target=\"_blank\">http:\/\/www.youtube.com\/watch?v=bqxxI_pwcXA<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Il s&#8217;agit de comprendre rapidement comment concevoir puis de coder &#8220;grosses mailles&#8221; une API. Les objectifs de cette exp\u00e9rience \u00e9taient les suivants : D\u00e9couvrir les&hellip; <\/p>\n<p class=\"text-center\"><a href=\"https:\/\/flaven.fr\/2014\/11\/slim-api-framework-les-bonnes-pratiques-pour-creer-une-api-avec-le-micro-framework-php-slim\/\" class=\"more-link\">Continue reading &rarr; <span class=\"screen-reader-text\">Slim, API, Framework &#8211; Les bonnes pratiques pour cr\u00e9er une API avec le micro-framework PHP Slim<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":10443,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bf_ai_meta_description":"Cr\u00e9er une API avec Slim, un micro-framework PHP. Les bonnes pratiques pour concevoir et coder une API fonctionnelle rapidement.","bf_ai_og_title":"API avec Slim - Bonnes pratiques","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[3439,3441,3442,3444,3448,3449,3450],"tags":[2127,2183,2126,2216,1893,192,245,2056,2125,2124,2123,182,90],"class_list":["post-10436","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apis-integration","category-data-analytics","category-mobile-devices","category-programming-databases","category-tools-productivity","category-tutorials-how-to","category-ux-product-design","tag-advanced-rest-client","tag-api","tag-eloquent","tag-framework","tag-google-chrome","tag-json","tag-kohana","tag-laravel","tag-orm","tag-silex","tag-slim","tag-symfony","tag-xml"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Vuhl-2Ik","jetpack_featured_media_url":"https:\/\/flaven.fr\/wp-content\/uploads\/2014\/11\/using_slim_bf.jpg","_links":{"self":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/10436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/comments?post=10436"}],"version-history":[{"count":21,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/10436\/revisions"}],"predecessor-version":[{"id":10474,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/10436\/revisions\/10474"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media\/10443"}],"wp:attachment":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media?parent=10436"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/categories?post=10436"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/tags?post=10436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}