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/

slim

  • 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

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/bootstrap-vue@latest/dist/bootstrap-vue.css"  />
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script src="https://unpkg.com/bootstrap-vue@latest/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.

 

frebourg-ninja-diagramme

 

 

  • 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