API SLIM
Slim is a micro Framework for PHP.
route bonjour – GET method, URI /bonjour
- install composer
- create a file composer.json
{ "require": { "php": "7.*", "ext-mbstring": "*", "ext-mysqli": "*", "ext-json": "*", "ext-pdo": "*", "ext-pdo_mysql": "*", "slim/slim": "3.*", "zircote/swagger-php": "^2.0", "firebase/php-jwt": "^5.0" } }
- in PHP7 or superior, using a command prompt, run
composer require slim/slim "3"
- in an index.php file, copy the code
<?php require 'vendor/autoload.php'; use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; $app = new \Slim\App; $app->get('/zaza', function(Request $request, Response $response){ return "wazaaaaaaaa"; }); $app->run();
- test on the server on localhost/index.php/
- test the zaza route
- modify the zaza route by bonjour to get the message: bonjour.
Example of client code functionSlim.js in JQ, to adapt into VueJS
$( document ).ready(function() $('#btn-valide').click(function(){ $.ajax({ type: "GET", contentType: 'application/json; charset=utf-8', url: "http://localhost/serveur/bonjour", success: function(data){ alert(data); } }); }); });
- start the server (apache or any other)
- test the route
- in a file /index.html, the page will call the route bonjour thanks to Ajax with the GET method.
</html>
———————————————————————– APACHE ANNEX————————————————————————————————————-
For the onlime implementation of the slim server and to avoid index.php on each route
In a .htaccess file. If the htaccess crashes the server, configurations of the Apache server are necessary. Remove the htaccess and add index.php to each uri.
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [QSA,L] Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept" Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Create your API with attributes in the URI
The database
- Adapt your database or use creation_db_zoo.sql et les csv annexes
Chambre route – GET method, URI /animal/{id}
- Choose and send an id of the animal to the SLIM server.
- The server will send the animal description back, thanks to a fouction and a call to the database.
Example of client code
$( document ).ready(function() { $('#btn-new-liste').click(function(){ let idx=$('#idx').val(); $.ajax({ type: "GET", url: "http://localhost/got/serveur/personnage/"+idx, success: function(data){ $("#result").html(data); } }); }); });
Example of addition of index.php code
$app->get('/personnage/{id}', function(Request $request, Response $response){ $id = $request->getAttribute('id'); return getPersonnage($id); }); function connexion() { return $dbh = new PDO("mysql:host=localhost;dbname=patisserie", 'root', '', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); } function getPersonnage($id) { $sql = "SELECT * FROM gateau"; try{ $dbh=connexion(); $statement = $dbh->prepare($sql); $statement->execute(); $result = $statement->fetchAll(PDO::FETCH_CLASS); return json_encode($result, JSON_PRETTY_PRINT); } catch(PDOException $e){ return '{"error":'.$e->getMessage().'}'; } }
Create your API with HTTP parameters
user route – GET method, URI /user
- Add a password to the user table
- Send the email and connexion.html password to the SLIM server.
- Test if the email and password exist thanks to a function and send the code 200 or 401 back.
Example of client code JQ
$('#btn-valide').click(function(){ let id=$('#id').val(); let nom=$('#nom').val(); $.ajax({ type: "GET", contentType: 'application/json; charset=utf-8', url: "http://localhost/got/serveur/user?id="+id+"&nom="+nom, success: function(data){ alert(data); } }); });
Example of cleint code VueJS
<!doctype html> <html lang="fr"> <head> <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" /> <link type="text/css" rel="stylesheet" href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" /> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> </head> <div id="app"> <b-container> <input v-model="idc" placeholder="numéro de chambre"/> <button v-on:click="ajax(idc)">valider</button> </b-container> </div> <script> var app =new Vue({ el: '#app', data () { return { idc: 0 } }, methods: { ajax: function (idc, event) { axios({ method: 'get', url: 'http://frebourg.es/api/index.php/chambre?idc='+idc, responseType: 'json', }) .then(async res => { if(res.status === 200) { alert('Ok!'); this.info=res.data; } else if(res.status === 400) { let errorResponse = await res.json(); this.errors.push(errorResponse.error); } }) } } }) </script> </html>
Example of an index.php code
$app->post('/user', function(Request $request, Response $response){ $tb = $request->getQueryParams(); $id = $tb["id"]; $nom = $tb["nom"]; //fonction de vérification d'utilisateur return checkUser($id, $nom); }); function checkUser($id, $nom) { $sql = "SELECT * FROM gateau"; try{ $dbh=connexion(); $statement = $dbh->prepare($sql); $statement->execute(); $result = $statement->fetchAll(PDO::FETCH_CLASS); return json_encode($result, JSON_PRETTY_PRINT); } catch(PDOException $e){ return '{"error":'.$e->getMessage().'}'; } }
user route – POST method, URI /user
- Create a user registration form inscription.html.
- Allow the addition of the user in the database.
Example of client code
$('#btn-valide').click(function(){ let id=$('#id').val(); let nom=$('#nom').val(); $.ajax({ type: "POST", contentType: 'application/json; charset=utf-8', url: "http://localhost/got/serveur/user?id="+id+"&nom="+nom, success: function(data){ alert(data); } }); });
Example of index.php code addition
$app->post('/user', function(Request $request, Response $response){ $tb = $request->getQueryParams(); $id = $tb["id"]; return insertUser($id, $nom); }); function insertUser($id, $nom) { $sql = "INSERT ..."; ... }
Create your API with the methods HTTP PUT and DELETE
user route – DELETE method, URI /user/{id}
- Implement the URI that suppresses aspecific user.
user route – PUT method, URI /user/{id}
- Implement the URI that modifies the email of a user.
rooms route – GET method, URI /animaux
- Implement the URI which sends back, in JSON the information of the animals.
- Create a page animaux.html wich displays all the animals in a table.
Secure your API with tokens
JSON Web Token (JWT) is an open standard defined in the RFC 7519. Available in most of the languages for a secured token exchange. You ab get the necessary extensions on the site jwt.io.
- Add JWT thanks to composer.
composer require firebase/php-jwt
- Allow a user to get a token valid 30 minutes when connecting to the site thanks to the URI /obtentionToken. Record this token in JavaScript session.
- In case of error when connecting (incorrect login and password) the server will send back an HTTP 401
Unauthorized
code.
Example of client code
$( "#btn-valide").click(function(event) { $.ajax({ type: "GET", url: urlServeur+"/obtentionToken", data: "pass="+ $("#password").val(), success: function(data){ sessionStorage.setItem('token', data); }, error: function(XMLHttpRequest, textStatus, errorThrown) { $(".form-group-password").addClass("has-danger"); $("#password").addClass("form-control-danger"); } }); });
Exemple of server code
<?php require 'vendor/autoload.php'; use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; use \Firebase\JWT\JWT; use Firebase\JWT\Key; $app = new \Slim\App; error_reporting(E_ALL); ini_set('display_errors', 1); $app->get('/obtentionToken', function(Request $request, Response $response){ //vérification de l'utilisateur $tb = $request->getQueryParams(); $login= $tb["login"]; $pass= $tb["pass"]; $allowed= ckeckUser($login,$pass); if($allowed){ $token=getTokenJWT(); return $response->withJson($token,200); }else{ return $response->withStatus(401); } }); $app->post('/verifToken', function(Request $request, Response $response){ $tb = $request->getQueryParams(); $token = $tb["token "]; if(validJWT($token)){ //J'execute la fonction }else{ //non autorisé return $response->withStatus(401); } }); function getTokenJWT() { // Make an array for the JWT Payload $payload = array( //30 min "exp" => time() + (60 * 30) ); // encode the payload using our secretkey and return the token return JWT::encode($payload, "secret"); } function validJWT($token) { $res = false; try { $decoded = JWT::decode($token, new Key($key, 'HS256')); } catch (Exception $e) { return $res; } $res = true; return $res; } $app->run();
- Secure the routes allowing to display the users thanks to the verification of a token. You can take the route /verifToken above as an inspiration.
- Secure all the routes allowing to modify, add or suppress an element (POST, DELETE, PUT).
Logs and dymamic graphs
We use Chartjs to generate dynamic graphs. There are other librairies.
- Create a page statistiques.html and display the 2 fowwing charts :
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css"> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" ></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js" ></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script> <div class="container"> <div class="row justify-content-md-center"> <div class="col-10"> <canvas id="myChart" ></canvas> <canvas id="myChart2" ></canvas> </div> </div> </div> <script> var backgroundColor=[ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ]; var borderColor=[ 'rgba(255,99,132,1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ]; var ctx = document.getElementById("myChart").getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: backgroundColor, borderColor: borderColor, borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }); var ctx2 = document.getElementById("myChart2").getContext('2d'); var myDoughnutChart = new Chart(ctx2, { type: 'doughnut', data : { datasets: [{ data: [10, 20, 30], backgroundColor: backgroundColor, borderColor: borderColor, borderWidth: 1 }], labels: [ 'Red', 'Yellow', 'Blue' ], } }); </script>
- Display, in the form of a diagram the number of animals by run.
- Display the number of races by keeper