Zend Framework

Utilisation de Zend REST : Partie 2

Comme promis, voici la partie 2 du tutoriel sur Zend REST. Dans celui-ci, nous allons aborder les choses suivantes :

  • Création et Utilisation d’une APIKEY
  • Utilisation des différentes méthodes http et test des retours JSON avec CURL.
  • Mise en place de codes retours http pour dire s’il y a eu une erreur ou non

Sachez que ce tutoriel est le dernier concernant Zend REST. Le prochain touchera à l’accès sur notre plateforme REST via Android.

I- Création et utilisation d’une APIKEY :

1 – Introduction :

L’APIKEY sert aux utilisateurs à s’authentifier sur votre application simplement, sans avoir quelque chose à taper. Vous pouvez avoir une APIKEY globale (ce que l’on va voir ici), une par utilisateurs, une par plateforme ou un mélange de tout ceci à la fois. A vous de voir ce qui vous convient le mieux. Pour notre exemple, nous allons choisir le plus simple, une APIKEY gobale. Si la requête n’est pas envoyée avec cette APIKEY, elle renverra une erreur. L’APIKEY de notre example sera la suivante :

6a0071dbe561c89581c56d1ecf3a4f54

Pour ceux qui aimeraient savoir ce que c’est, cette APIKEY n’est qu’un simple MD5 de throrinstudio. 

2 – Mise en place :

Maintenant, il faut peut-être dire à Zend que nous voulons utiliser cette APIKEY et, si elle est mauvaise, refuser la requête. Nous allons donc créer un plugin pour notre Controller. Si vous ne savez pas ce que c’est, voici un petit rappel de la documentation :

L’architecture MVC de Zend Framework propose l’injection de plugins de code, qui vont intervenir à différents niveaux dans le processus complet. Le contrôleur frontal enregistre des plugins, et utilise un gestionnaire de plugins (« plugin broker »), qui va se charger de faire intervenir chaque plugin, à chacun des instants clés à votre disposition.

Donc, nous allons créer le plugin RestAuth suivant :

class App_Controller_Plugin_RestAuth extends Zend_Controller_Plugin_Abstract{

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $apiKey = $request->getHeader('Api-Key');

        //on récupère notre fichier de configuration
        //car notre apikey est stoquée dedans
        $config = Zend_Registry::get('config'); 


        //Si notre apikey est mauvaise alors qu'on essaie d'accéder à notre module rest et qu'on est pas sur la page d'erreur, 
        //on renvoie vers la page d'erreur
        if($apiKey != $config['tutorest']['apikey'] && $request->getModuleName() == "rest" && $request->getControllerName() != "error") {
            //Ici, on met le code 403 ACCES_DENIED à notre réponse HTTP
            $this   ->getResponse()
                    ->setHttpResponseCode(403);
            //Et on redirige vers le controller d'erreur
            $request->setModuleName('rest')
                    ->setControllerName('error')
                    ->setActionName('api')
                    ->setDispatched(true);
        }

    }
}

Comme on peut le voir, on redirige en cas d’erreur sur un controller d’erreur créé pour l’occasion. Voici son code :

class Rest_ErrorController extends Zend_Controller_Action{

    public function init()
    {
        $bootstrap = $this->getInvokeArg('bootstrap');
        $options = $bootstrap->getOption('resources');

        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch  ->addActionContext('api', array('json'))
                        ->initContext('json');
    }

    public function apiAction(){
        $this->view->error = "APIKEY is wrong";
    }
}

Et maintenant, nous allons dire à Zend de charger notre plugin pour faire le test. Nous allons l’initialiser dans le Bootstrap de notre module Rest :

class Rest_Bootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initAutoload()
    {
            $moduleLoader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'Rest',
            'basePath' => APPLICATION_PATH . '/modules/rest'));
            return $moduleLoader;
    }

    protected function _initPlugins(){
        $bootstrap = $this->getApplication();
        $bootstrap->bootstrap('frontcontroller');
        $front = $bootstrap->getResource('frontcontroller');

        $front->registerPlugin(new App_Controller_Plugin_RestAuth());
    }
}

Maintenant, si vous essayez d’accéder au site via http://votresite/rest/ vous devriez avoir le JSON suivant :

{"error":"APIKEY is wrong"}
Attention, il se peut qu’à la place vous ayez le message suivant :  Fatal error: Uncaught exception ‘Zend_Exception’ with message ‘No entry is registered for key ‘config »… Si vous avez ce message, rien de grave, c’est que vous n’avez pas initialisé la variable de registre config à partir du Bootstrap principal. Si c’est votre cas, voici la fonction à rajouter :

protected function _initConfig()
{
Zend_Registry::set(‘config’, $this->getOptions());
}

Maintenant que nous avons mis en place l’apikey, nous allons voir comment la renseigner à notre requête.

3 – Utilisation :

Pour cette partie, nous allons effectuer nos requêtes via curl en ligne de commande linux. Ici j’utilise putty connecté sur mon serveur de test. Avant de pouvoir utiliser CURL, vous devez l’avoir d’installé sur votre machine. Si ce n’est pas le cas, faites le :

sudo apt-get install curl

Ensuite pour interroger le serveur comme le fait votre navigateur, vous aurez juste à taper la commande suivante. Attention, elle vous retournera la même erreur que par le navigateur.

curl http://localhost/tutosite/rest/tuto -v

Si vous avez bien regardé le plugin de vérification de l’apiKey, vous pouvez voir que l’on récupère cette clé directement dans le header HTTP de la façon suivante :

$apiKey = $request->getHeader('Api-Key');

Nous allons donc dire à CURL de rajouter une nouvelle en-tête à la requête HTTP du nom ‘Api-Key’ et contenant notre clé :

curl http://localhost/tutosite/rest/tuto -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

En retour vous devriez avoir le bon JSON. Voilà, maintenant vous savez comment renseigner votre api-key directement dans les headers HTTP. Maintenant nous allons passer aux différents types de requête.

II- Méthodes HTTP et REST :

1 – index et GET :

C’est la méthode la plus courante pour demander une ressource. Une requête GET est sans effet sur la ressource, il doit être possible de répéter la requête sans effet. la méthode getAction() sera appelée lorsque l’on cherche à récupérer une ressource en particulier. Si nous ne demandons rien de particulier, c’est la méthode indexAction() qui est appelée à la place. Par exemple pour récupérer une liste, on va dans index, pour récupérer un livre en particulier, on va dans get. 

La commande curl précédente nous permettait d’aller dans notre méthode index. Pour accéder dans la méthode get, il suffit juste d’effectuer la commande suivante en renseignant dans le lien l’id de l’élément à chercher :

curl http://localhost/tutosite/rest/tuto/1 -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

En réponse vous devriez avoir le JSON correspondant à celui de getAction.

2 – POST :

Cette méthode doit être utilisée pour soumettre des données en vue d’un traitement à une ressource (typiquement depuis un formulaire HTML). L’URI fournie est l’URI d’une ressource à laquelle s’appliqueront les données envoyées.

Le résultat peut être la création de nouvelles ressources ou la modification de ressources existantes. À cause de la mauvaise implémentation des méthodes HTTP par les navigateurs, cette méthode est souvent utilisée en remplacement de la requête PUT, qui devrait être utilisée à la fois pour la création et la mise à jour de ressources.

Voici la commande permettant de tester le POST :

curl -d "article=myarticle"   http://localhost/tutosite/rest/tuto/ -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

3 – PUT :

Cette méthode permet de remplacer ou d’ajouter une ressource sur le serveur. L’URI fourni est celui de la ressource en question. PUT et POST pourraient être tous les deux utilisés pour effectuer la même chose. Normalement j’utilise POST pour la création et PUT pour la modification. Après à vous de voir ce que vous préférez. Voici la commande permettant de tester le PUT:

curl -d "article=myarticle" -X PUT  http://localhost/tutosite/rest/tuto/ -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

4 – DELETE :

Cette méthode permet de supprimer une ressource du serveur. Normalement, après exécution de cette requête il ne devrait pas y avoir de réponse HTTP mis à par le status HTTP. Ici nous allons avoir un retour car nous n’avons pas établis les codes retours :

curl -X DELETE  http://localhost/tutosite/rest/tuto -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54

III- Codes retours :

Afin de savoir si nos requêtes se sont bien passées ou pas, nous regarderont le code retour HTTP avant de traiter le JSON de retour. Comme cela, nous saurons s’il s’agit d’un JSON de ressources à traiter, de confirmation, d’erreur, … Pour faire ceci, nous rajouterons à chacune de nos fonction la commande suivante :

$this->getResponse()->setHttpResponseCode($code);

Nous nous baserons sur les codes retour HTTP. Ce sera plus simple pour les traiter et en même temps ça servira de piqûre de rappel pour certains 😉 :

  • 200 : Requête traitée avec succès (utilisée pour index et GET
  • 201 : Requête traitée avec succès avec création d’un document (utilisée pour PUT et POST)
  • 204 : Requête traitée avec succès mais pas d’information à renvoyer (utilisée par DELETE)
  • 400 : La syntaxe de la requête est erronée (peut être utilisée si vous passez les mauvais paramètres de recherche et/ou d’ajout)
  • 403 : L’authentification est refusée. (utilisée quand APIKEY est invalide)
  • 404 : Ressource non trouvée (peut être utilisée dans GET et PUT/POST quand la ressource à récupérer/modifier n’existe pas)
  • 500 : Erreur interne du serveur (utilisée pour toute erreur PHP ou tests invalides autre que ceux gérés au dessus)
Après à vous de décider. Je n’ai pas mis toute la liste mais seulement l’énumération et les Use Cases des principaux codes de retour.

Le code de retour 204 ne retournera aucun contenu même si vous en renseignez un. Donc pour vérifier que l’action DELETE s’est effectuée avec succès, testez juste le code de retour. Si c’est 204, tout s’est bien passé.

Conclusion Partie 2.

Dans cette partie vous aurez vu comment toucher au header HTTP, comment modifier le code de retour et comment vérifier tout ceci sous Zend. Vous aurez aussi appris à vous servur de curl en ligne de commande (peut être un tutoriel sur curl et Zend dans un prochain tutoriel ?). Avec ceci vous avez toutes les bases pour créer votre propre service REST. La prochaine fois nous verrons comment consommer ce service grâce à une application Android. Sur ce, je vous souhaite une bonne fin de semaine.