2012-12-01 3 views
7

J'ai développé une application PHP très simple et rapide pour lire des petites annonces à partir d'un fichier XML et permettre à l'utilisateur d'effectuer des opérations CRUD (c'était un devoir).Créer une API RESTful en PHP?

Je suis maintenant chargé de développer cette application pour un service RESTful. En fait, le professeur ne semble pas avoir d'expérience avec les services RESTful, car il a dit que mon application a été trouvée pour la prochaine affectation, quand mes recherches indiquent qu'elle ne répond pas vraiment à toutes les exigences de RESTful. Quoiqu'il en soit, je veux le faire correctement à des fins d'apprentissage, même si je peux remettre mon ancienne tâche et obtenir une bonne note. J'ai de la difficulté à apprendre par où commencer; Je ne suis pas sûr exactement ce qu'est vraiment un service RESTful.

Je pense que la meilleure façon d'obtenir des conseils est de poster un exemple de code de ma précédente mission pour voir comment j'ai géré les choses et comment je dois gérer les choses à la place.

Par exemple, voici comment je crée de nouvelles petites annonces.

create.php

//Basically just a list of <INPUT TYPE = "text" NAME = "something"> in the <body> fields 

CreateSuccess.php

<html><head><?php $simplerXML = simplexml_load_file('file.xml'); 
//Generate the basic ad information 
$newAd = $simplerXML->addChild('advertisement',''); 
$newAd->addAttribute('category', $_POST["category"]); 
$title = $newAd->addChild('title', $_POST["title"]); 
$title->addAttribute('ID', $_POST["ID"]); 
$pageTitle = $newAd->addChild('pagetitle', $_POST["pagetitle"]); 
//etc, for all the SUBMIT boxes 

//save the XML 
$simplerXML->asXML('file.xml'); 
echo "<script type='text/javascript'> 
//redirect back to ad listing page 
window.onload = function() { top.location.href = 'ads.php'; }; 
</script>"; 
?></head> 
<body></body></html> 

J'utilise aussi des paramètres d'URL pour les actions RUD. J'ai entendu dire que les paramètres d'URL ne sont pas autorisés?

Merci. Donc, l'instruction SWITCH, va-t-elle dans le fichier index.php? Et puis chaque cas appellera une fonction, à savoir CreateXML pour la méthode POST? Ensuite, les paramètres dont il a besoin seront le type d'objet, l'ID d'objet et le type de contenu? Comment puis-je obtenir les valeurs pour mettre à jour le XML, dois-je simplement l'envoyer au fichier Create.php contenant la liste des boîtes de saisie?

+0

En ce qui concerne vos questions supplémentaires: oui, vous pouvez mettre le 'switch' dans votre index. php, ou si vous voulez entrer dans une architecture plus complexe, vous pouvez amorcer un composant de routeur externe qui gère le routage. L'analyse URI était pour référence seulement - je ne pense pas que vous en aurez besoin pour votre application. Compte tenu de la simplicité de votre application, vous pouvez simplement analyser et router la méthode de requête pour éditer votre fichier unique. Ce serait encore RESTful. –

+1

Plus généralement, RESTfulness concerne * interface *, pas * implementation *. –

Répondre

15

Si votre service prend en charge toutes les opérations CRUD, il est toujours conseillé d'implémenter une interface RESTful. Ce n'est pas super difficile de le faire. J'ai décrit certaines des bases ci-dessous.

Un service RESTful fait simplement quelques petites choses:

  1. Il utilise la méthode de requête HTTP pour la communication de l'action CRUD
  2. Il utilise le code d'état HTTP pour communiquer l'état de réponse et
  3. Il utilise le URI pour définir votre ressource (fichier, élément de base de données auquel vous accédez, etc.).
  4. Il est apatride

L'idée est de réduire au minimum le développement des communications sur mesure pour ces choses qui sont déjà définies dans la spécification HTTP.


1 - DEMANDE LA METHODE

Les méthodes de demande 4 HTTP vous nécessaire pour soutenir un service RESTful sont:

  1. POST
  2. GET
  3. PUT
  4. DELETE

et vous pouvez éventuellement prendre en charge

  1. PATCH
  2. TÊTE

Vous pouvez mapper ces directement à vos actions CRUD comme suit:

  • POST = Créer
  • GET = Récupérer
  • PUT = Mise à jour
  • SUPPRIMER = Supprimer
  • PATCH = Modifier (une mise à jour partielle, par exemple, "changer le mot de passe". PUT devient "remplacer")
  • HEAD = En-tête uniquement (métadonnées sur la ressource)

Pour ce faire, les demandes d'itinéraire correctement avec un routeur de méthode simple de demande comme suit:

switch ($_SERVER["REQUEST_METHOD"]) { 
    case "POST": 
     // Create action 
     break; 
    case "GET": 
     // Retrieve action 
     break; 
    case "PUT": 
     // Update action 
     break; 
    case "DELETE": 
     // Delete action 
     break; 
} 

2 - CODE D'ÉTAT Vous devez en outre implémenter les codes d'état HTTP de votre service pour communiquer l'état au client, par exemple:

  • 20x = succès
  • 30x = redirection
  • 40x = Problèmes de communication
  • 50x = erreur de serveur

Pour ce faire, préfixer simplement votre réponse avec la sortie d'en-tête HTTP appropriée, par exemple:

header("Status: 500 Internal Server Error"); 

Vous pouvez consulter la liste complète des codes d'état HTTP implémentés ici: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


3 - URIs Pour URIs, les services RESTful suivent généralement une approche descendante pour nommer catégorisés, par exemple

/object_type/id.content_type 

Exemples:

POST /user 
PUT /user/1 
GET /user/1.json 
GET /user/1.html 

Vous pouvez mettre en place un routeur RESTful très rudimentaire pour la convention ci-dessus en utilisant Apache avec mod_rewrite dans un fichier .htaccess, comme suit:

RewriteEngine On 
RewriteRule ^([^\/]+)\/([^\.]+)\.(\w+)$ index.php?object_type=$1&object_id=$2&content_type=$3 

alors vous avoir index.php Recherchez le type d'objet et l'ID appropriés à router de manière appropriée, par exemple:

$object = $_GET["object_type"]; 
$id = (int) $_GET["object_id"]; 
$content_type = $_GET["content_type"]; 

// Route from here to a class with the name of the object (e.g. UserController) via __autoload 
// or to a file (e.g. user.php) via include, and pass id and content_type as params 

4 - APATRIDIE Simplement dit, le serveur maintient l ' "état" pour le client. Aucune exigence pour stocker la session ou le statut. Chaque requête représente une transaction complète. C'est à dire. Si je GET utilisateur/1, le serveur ne se souviendra pas que je l'ai fait, et les demandes futures ne seront pas dépendantes ou affectées par les précédentes. Si vous mettez en œuvre ces normes, félicitations, vous avez construit un service RESTful!

+0

très bonne réponse, bravo! – m4t1t0

+0

Merci beaucoup pour votre réponse détaillée. Je peux voir que vous l'avez édité un peu et le temps que vous avez passé est très apprécié. J'ai quelques autres questions d'éclaircissement que j'ai éditées, si vous pouviez jeter un coup d'oeil. – user1287523

+0

Désolé de relancer, mais ne devrait pas 'POST/user/1.xml' être' POST/user'? Comment connaissons-nous le numéro si non? Merci. – JorgeeFG

4

"RESTful" est un concept large et il existe des degrés de "RESTfulness". Wikipedia est un bon guide ici

Voici quelques caractéristiques de niveau supérieur ne sont pas abordées dans l'autre réponse (qui est aussi bon):

  1. ressources sont disponibles à des URL, de préférence avec une seule URL canonique par ressource .
    • Vous pouvez indiquer qu'une ressource est disponible dans d'autres URL ou représentations à l'aide de l'en-tête Content-Location.
    • Vous pouvez fournir différentes représentations d'une ressource (html, json, xml, etc.) en utilisant la négociation de contenu avec les en-têtes Accept et content-type.
  2. Les modifications de l'état de la ressource sont entièrement représentées par une requête HTTP unique. Le serveur n'a pas besoin de gérer l'état pour traiter une demande client. Par conséquent, les demandes peuvent être facilement transmises par proxy et mises en cache.
    • Un exemple d'une violation commune de ce principe est une URL comme « http://example.org/profile » qui sert un profil d'utilisateur différent en fonction de qui est connecté.
    • Il serait mieux séparez la ressource de l'autorisation: "http://example.org/profile/{USERID}" servira toujours l'ID utilisateur d'un utilisateur particulier, mais retournera 401 (Non autorisé) si le client n'a pas l'autorisation. (De plus, les informations d'autorisation doivent être envoyées avec chaque requête, afin que le serveur ne nécessite pas de jeton de session ou d'état similaire côté serveur.) Par conséquent, la plupart des sites Web avec un système de connexion basé sur les cookies sont purement reposants.
    • Obtenir pour récupérer une ressource. Cela ne devrait pas changer l'état de la ressource et devrait être reproductible en toute sécurité. Cette propriété est souvent appelée "Idempotency".
    • PUT pour mettre à jour une ressource.En utilisant des techniques telles que conditional updating requests (PUT ou DELETE avec un en-tête if-*), vous pouvez même implémenter un contrôle de concurrence optimiste.
    • SUPPRIMER pour supprimer une ressource.
    • POST comme ressource catchall "faire quelque chose". POST est utilisé lorsque vous devez faire quelque chose qui ne convient pas aux méthodes http ou lorsque vous devez effectuer une action avec des effets secondaires (par exemple, créez une nouvelle ressource sans connaître son nom ou implémenter un protocole RPC). Cependant, vous devez utiliser les en-têtes http et les codes de réponse pour montrer les effets secondaires des ressources, par ex. un "201 Créé" avec Location et Content-Location en-têtes et une liste d'URL affectées par le changement.
  3. Les représentations de ressources sont auto-descriptives "hypertexte" avec des liens vers d'autres ressources.
    • Un exemple d'une violation de ce principe: Supposons que « http://example.com/articles » est une liste d'articles et la représentation JSON de celui-ci ressemble à [1,2,3,4,5,6]. C'est une liste d'identifiants d'articles, mais ce n'est pas auto-descriptif ou hypertexte - le client a besoin de savoir qu'il s'agit d'une liste d'identifiants d'articles, et il doit savoir que pour obtenir une ressource article il doit construire une URL comme " http://example.org/articles/1 ".
    • Mieux serait une réponse comme {"articles":[{"id":1,"url":"http://example.org/articles/1"},...]}. Comme html, un client utilisant un service de repos devrait seulement avoir suivre liens (pas faire liens) pour obtenir d'autres ressources. Vous pouvez même documenter les méthodes disponibles que vous pouvez utiliser pour manipuler une ressource - créer, mettre à jour, supprimer, etc.