web-dev-qa-db-fra.com

Bien PHP Reste la bibliothèque Api

Je développe un système multi-plateforme et je dois faire une API de repos pour les lier ensemble. J'ai une longue expérience de PHP et je souhaite l'utiliser pour ce service.

Je pourrais développer une API à 100% manuellement, mais j'espère qu'il existe d'excellentes bibliothèques qui pourraient faciliter mon développement.

Quelqu'un at-il une expérience avec des bibliothèques comme celle-ci? Quelque chose que vous pourriez recommander?

14
OptimusCrime

J'ai reçu le badge Popular question pour cette question, alors je pense qu'il est temps que je précise comment j'ai fait ma solution REST.

J'ai regardé à la fois Laravel, Sympfony2 et Codeigniter pour cette REST Api. Ils avaient tous des éléments que j'aimais et d'autres que je n'aimais pas. Ma principale préoccupation était de savoir comment procéder à l'authentification, car j'avais un algorithme assez complexe dans lequel mes utilisateurs pouvaient se connecter à l'aide des tables access_token ou access_tokens fournies par Google ou Facebook. Je me suis également rendu compte que je maîtrisais parfaitement mon framework, et les frameworks mentionnés ci-dessus comportaient certains éléments que je jugeais inutiles et difficiles à contourner. À cause de cela, j'ai décidé de créer ma propre solution REST. Ce n'est pas aussi difficile qu'on pourrait s'y attendre, et cela peut se faire de plusieurs manières. La façon dont je l'ai fait nécessite des connaissances en programmation POO.

Okey, donc démarrant une classe de base appelée REST. Cette classe s’occupe de tout ce qui est commun à chaque appel. Comme l’authentification, analyser le chemin demandé à une méthode, vérifier access_token etc.

L'un des éléments centraux de cette classe est le chemin demandé et sa traduction en méthode. Je l'ai fait inspiré par Laravel. J'ai un tableau avec key => value où la clé est l'URL qui doit correspondre et la valeur est la méthode à appeler. J'ai également inclus la façon dont Lavavel analyse les variables dans l'URL comme ceci:

'/user/(:id)' => 'user_id',

Cela correspondrait à n'importe quel/utilisateur/[numéro]. Il vérifie également le type de requête dont il s'agit, donc s'il s'agit d'une méthode get simple, il essaiera d'appeler get_user_id. Tout ce qui est analysé avec (:id) sera utilisé comme argument lors de l'appel de cette méthode (donc, elle appelle en fait get_user_id($id)).

Après authentification, l'appel de méthode réel est évalué. Je ne souhaitais pas utiliser toutes les méthodes (comme get_user_id) dans la classe REST elle-même. Je les ai donc réparties dans différents contrôleurs qui étendent la classe REST. Ceci est fait en regardant l'URL demandée. S'il s'agit de /user/(:id), le script vérifiera s'il existe un contrôleur nommé userController.php. S'il existe, vérifiez si la méthode à appeler existe. Si c'est le cas, vérifiez si le nombre d'arguments correspond à ce que nous avons. Si tout va bien, exécutez la méthode, sinon renvoyez un message d'erreur. La structure et les messages d'erreur sont très importants lors de la création d'une API de ce type. 

Dans les différents contrôleurs, j'appelle le constructeur de la classe REST pour obtenir l'authentification, l'analyse de l'URL, etc. résolue. La partie délicate ici est que je ne voulais pas faire:

$controller = new MyController();
$controller->printResponse();

Au bas de chaque contrôleur. J'ai donc créé un petit hack et un script appelé run.php qui le fait de manière dynamique pour chaque classe de contrôleur. Avant d’inclure le run.php, je sauvegarde le chemin du contrôleur en effectuant simplement $path = explode('/',__FILE__);. Ceci est utilisé dans le run-script. Le script d'exécution ressemble à ceci:

// Splitting the file-name, removing the extension
$name = explode('.',$path[count($path)-1]);

// Uppercasing the first letter to be Nice and OOP-ish
$classToCall = ucfirst($name[0]);

// Creating a new instance
$controller = new $classToCall();

// Logging
$controller->doLog();

// Printing the final response
$controller->printResponse();

J'ai trouvé que c'était une solution parfaite pour la façon dont je voulais construire mon API. Je peux facilement ajouter de nouvelles méthodes en le fournissant dans le tableau qui analyse les URL en méthodes, et je peux ajouter de nouvelles méthodes dans les contrôleurs bien séparés pour une propreté maximale.

Certaines personnes pensent peut-être que cela représente trop de travail, mais il ne m'a fallu que quelques heures pour le rendre opérationnel. J'appellerais aussi cela un processus très dynamique car je peux simplement ajouter de nouveaux contrôleurs et le système les reconnaîtra s'il s'agit de modèles d'URL valides.


Quelques conseils amicaux.

Si vous décidez d’utiliser quelque chose qui ressemble à cette solution, voici quelques bons conseils. Dans chaque contrôleur, faites quelque chose comme ceci:

public function __construct() {
    // Loading the class-name, setting it in the REST-class, so we can check if it holds the method being called
    $this->className = get_class($this);

    // Calling RESTs constructor
    parent::__construct();
}

Nous aurons besoin de stocker la classe à partir de laquelle nous travaillons actuellement. Ce serait UserController ou quelque chose comme ça.

Dans la classe REST, je peux ensuite utiliser cette variable pour vérifier si la méthode effectivement appelée est présente dans ce contrôleur. Je l'ai fait de cette façon:

// Checking if the method exists
if (method_exists($this->className,$method_name)) {
    // Check to see if we have the required number of arguments represented
    $ReflectionClass = new ReflectionClass($this->className);

    if ($ReflectionClass->getMethod($method_name)->getNumberOfParameters() == count($this->methodUrl['args'])) {
        $this->response['response'] = call_user_func_array(array($this, $method_name), $this->methodUrl['args']);

J'espère que cela peut vous aider.

Happy codin '

14
OptimusCrime

J'ai eu la même question il y a trois mois. J'ai passé de nombreuses heures à rechercher les meilleurs PHP frameworks à utiliser. Finalement, je me suis installé sur Laravel

Il est livré avec des routes et des contrôleurs RESTful, ainsi qu’une authentification facile à utiliser. J'avais une API REST simple en un jour environ

http://laravel.com/docs/routing#the-basics

http://laravel.com/docs/controllers#restful-controllers

Il est également livré avec un excellent ORM qui facilite la configuration des ressources.

http://laravel.com/docs/database/eloquent

J'utilise la version 3.2 et cela fonctionne comme un charme et est stable. La version 4 est toujours en version bêta, mais a beaucoup plus de fonctionnalités orientées REST (je pense que l'une d'elles est qu'elle facilite la création de ressources à partir de vos contrôleurs)

Grand tutoriel ici http://net.tutsplus.com/tutorials/php/laravel-4-a-start-at-a-restful-api/

1
Gaz_Edge