Sei sulla pagina 1di 15

Il sito web è stato creato con HTML5 e CSS3, e PHP, per richiedere i servizi offerti dal web service

di tipo REST implementato con l’utilizzo del framework Slim.

Il nostro web service permette di gestire gli utenti registrati e gli hotel aggiunti nel nostro database.

Rest
Rest (REpresentational State Transfer) è un tipo di architettura software che si basa sui seguenti
principi:
 Identifica tutto come URI – Rest utilizza tutto come risorsa e assegna un identificativo
(come l’URL) a quella risorsa.
 Utilizzo degli Hypermedia – la transizione degli utenti attraverso la web application
avviene solo tramite le risorse come hyperlinks.
 Le richieste sono Stateless – L’idea centrale di Rest è quella di essere senza stati. Cioè
ogni richiesta gestita dal server può esere eseguita senza sapere nulla riguardo i requisiti
precedenti.
 Utilizzo di Protocolli Standard – La maggiorparte delle applicazioni REST utilizzano http
per la sua semplicità. http usa quattro operazioni di base (GET, PUT, POST, and DELETE)
per fare tutte le operazioni.

Dunque un web service che implementa questi principi è detto Restful web service.
Slim

“Slim is a PHP micro framework that helps you quickly write simple yet powerful web
applications and APIs. At its core, Slim is a dispatcher that receives an HTTP request,
invokes an appropriate callback routine, and returns an HTTP response. That’s it.”

Come riportato sul sito ufficiale, Slim è un micro framework che aiuta nella progettazione di
semplici ma potenti applicazioni web ed API. Al suo nucleo Slim è un dispacher che riceve
richieste HTTP e invoca appropriate routine di funzioni callback e restituisce una risposta HTTP.
Un micro framework è un framework che implementa i componenti assolutamente necessari
lasciano il framework il più semplice possibile ma comunque estensibile (cioè si possono
aggiungere altri componenti se necessari).
Come lavora slim con le richieste e rsiposte HTTP? Definendo due interfacce:
Psr\Http\Message\RequestInterface e Psr\Http\Message\ResponseInterface rispettivamente.
Vediamo una semplice implementazione con questo codice “Hello Name”:

Nel nostro caso però si ha avuto la necessità di eseguire operazioni più complesse e tutte legate
all’utilizzo del database, quindi la prima cosa che abbiamo fatto è stato eseguire una connessione
al database.
Connessione al database

Innanzitutto abbiamo definito e assegnato le variabili relative alle informazioni sul database,
abbiamo poi definito una funzione nella quale, tramite la classe PDO (PHP Data Object), si esegue
la connessione al database e si impostano gli attributi per il report degli errori.

Di seguito si descrivono esempi di implementazione della nostra slim app:

Proviamo ad esempio a richiedere tutti gli hotel presenti nel database, che saranno poi mostrati
nella pagina iniziale della Web app.
Osserviamo anche in questo caso si è utilizzato il metodo get ma abbiamo utilizzato un path
differente.
In questo caso la prima operazione è stata quella di salvare la query in una variabile che nel
blocco try-catch, dopo aver creato un oggetto della classe db e stabilita la connessione
richiamando la funzione connect( ), viene eseguita. A questo punto grazie alla classe PDO si può
salvare il risultato della query in una variabile tramite lo statement PDO::FETCH_OBJ che ritorna
ogetti della classe stdClass.
Infine si chiude la connessione e si codifica il risultato ottenuto in formato Json.

Si riporta ora un esempio che richiede l’uso del metodo Post: l’aggiunta di utenti nel database.
In questo caso dato che viene inserito “codice” da parte dell’utente, questo codice può essere
anche malevolo e per questo, come possiamo notare, le istruzioni sono leggermente diverse.

Dopo aver ottenuto e salvato nelle variabili le informazioni inserite dall’utente, si passa alla
connessione col database come nel caso precedente. Questa volta, però, non viene eseguita
subito la query ma viene “preparata”, cioè si definisce uno schema della query che solo dopo il
bind dei parametri con i rispettivi placeholder può essere eseguita.
Questo meccanismo è denominato binding dei parametri perché essi sono appunto vincolati dallo
statement PDO (in questo caso per esempio abbiamo tutti PDO::PARAM_STR che rappresenta un
tipo di dato stringa).
Come ultimo esempio si riporta il seguente che utilizza il metodo delete che permette
l’eliminazione dal database di un utente inserendo l’id dell’utente che si vuole eliminare.
Questa operazione deve essere compiuta da un amministratore quindi non è richiesto il bind dei
paramentri.

Prima di vedere come il sito web interagisce con il web service, però, è opportuno visualizzare la
documentazione creata con Swagger.
Swagger
Swagger è un insieme di tools che permettono l’implementazione della specifica OpenAPI che definisce
uno standard per la descrizione di API RESTful. Il formato del documento generato è sia machine-readable
che human-readable e permette di scoprire e comprendere le funzionalità del servizio senza accedere al
codice sorgente o alla documentazione.

Alcune domande a cui cerca di rispondere sono le seguenti:

 Quali sono le operazione che l’API supporta?


 Quali sono I parametri dell’API e cosa restituisce?

Swagger, come detto, implementa diversi tool, tra i quali riportiamo:


 Swagger Editor: l’editor permette di modificare la specifica OpenApi in YAML all’interno del
browser e di avere un’anteprima della documentazione in real time.
 Swagger UI: la Swagger User Interface è un insieme di HTML, Javascript, e CSS che dinamicamente
generano la documentazione grazie ad un compilatore integrato.

Swagger Editor

Il linguaggio utilizzato per implementare la specifica OpenApi è YAML.


Come riportato sul sito yaml.org: “YAML (YAML Ain't Markup Language) is a human friendly data
serialization standard for all programming languages.”( serialization is the process of translating data structures or object state into a format that can
be stored) Vediamo un semplice esempio:

Come possiamo vedere da questo esempio YAML è un linguaggio molto facile da leggere e comprendere,
tuttavia Swagger implementa la OpenAPI Specification (OAS), precedentemente nota come Swagger
Specification, dunque è necessario seguire l’insieme di regole definite da questo formato che sono descritte
nel seguente link: swagger.staging.wpengine.com/specification/

Descriviamole brevemente utilizzando come esempio proprio la specifica del nostro web service,
riportiamo innanzitutto i " Fixed Fields " principali utilizzati nella descrizione della nostra API:
I campi obbligatori sono: openapi, info, paths.

openapi: descrive la versione della specifica


OpenAPI utilizzata nel documento.
info: fornisce metadata riguardo API.
paths: descrive I percorsi disponibili e le
operazioni della API.
tags: lista di tags utilizzati dalla specific ache
riportano addizionali metadata.
servers: fornisce informazioni sulla connettivita
di un server target.
components: elemento che contiene diversi
schemi per la specifica.

Com’è possibile osservare dall’immagine a


fianco, ognuno di questi campi è a sua volta
composto da altri campi che possono, ancora
una volta,essere obbligatori o meno.
Soffermiamoci ora sulla descrizione dei
campi che compongono paths e components.

paths è formato da uno o più oggetti /{path}


che sono percorsi relative ad un endpoint
unico, il campo deve iniziare con uno slash.
Ogni oggetto descrive le operazioni
disponibili sel singolo percorso.
A sua volta l’oggetto Path è formato da un
oggetto di tipo Operation che descrive una
singola operazione API su un percorso.
Con il seguente esempio riportiamo quali sono i campi che descrivono gli oggetti Path:
In questo caso l’oggetto operation è “get” che definisce che l’operazione su questo path è di
tipo GET.

Il campo tags riporta i tags in cui appartiene questo oggetto, summary, descrive in breve
cosa fa l’operazione, operationid è una stringa unica usata per identificare l’operazione,
responses, che è l’unico campo obbligatorio, è una lista di possibili risposte ottenute
dall’esecuzione dell’operazione.
Se l’operazione ha dunque avuto successo restituendo il codice di stato 200 questo, si ottiene
il contenuto della risposta in formato Json, dunque in questo caso si ha un array contenente
tutti gli hotel contenuti nel database in formato Json.
Lo schema degli hotel è quindi definito mediante un riferimento esterno descritto dal campo $ref:

Dunque riportiamo lo schema dell’hotel all’inteno del


campi: componente/schema/hotel.
Come possiamo vedere L’hotel è definito come tipo
oggetto che possiede diverse proprietà tutte di tipo
stringa, e ogni proprietà è richiesta, cioè obbligatoria.

Ecco dunque come appare il modello dell’oggetto


Hotel:

Swagger UI

Non resta che mostrare la Swagger UI come appare una volta compilata la specifica della nostra API:
Possiamo osservare infatti come appare la Swagger UI che riporta la documentazione della’API generata a
partire dal codice YAML. Se infatti estendiamo l’operazione descritta precedentemente, possiamo vedere
tutte le informazioni necessarie: Url in cui si invia la richiesta, parametri richiesti, codici di stato di risposta
ed esempio del modello di risposta.
CURL
Dopo analizziamo ora come il sito web interagisca con la nostra API.

cURL è una libreria che permette di eseguire richieste HTTP in PHP.

Ci sono essenzialmente quattro step che definiscono ogni attività cURL:

 Inizializzare una risorsa cURL.


 Impostare ogni opzione necezzaria.
 Eseguire la chiamata http.
 Analizzare la risposta di ritorno.

//CURLOPT_URL – questa opzione specifica quale su URL si vuole operare, in questo caso
questa specificata dalla variabile $url chepiene passata come parametro.

//CURLOPT_RETURNTRANSFER – impone a cURL di non inviare direttamente la risposta al


browser ma di ritornarla come stringa tramite curl_exec().
Dunque nel file index.php per mostrare gli hotel presenti nel database basta creare un nuovo
oggetto della classe curl e passare l’url http://slimapp/api/hotel alla funzione curlf($url) che si
occuperà di eseguire la chiamata http.
Il risultato viene salvato nella variabile return anziché essere visualizzata direttamente nel browser.
Essendo il risultato in formato JSON deve essere prima decodificato e una volta fatto ciò possiamo
rappresentare il risultato nella web app.

Osserviamo che se stampiamo a schermo la variabile decode otteniamo il seguente array di


stdClass Object.

Dunque per accedere al valore dell’oggetto stdClass a cui siamo interessati accediamo prima ad
ogni elemento del nostro array e poi al singolo valore.
Mostriamo infine come appare il risultato dell’operazione ricordando che i valori sono inseriti in
oppurtini heading ognuno dei quali ha subito una leggera modifica di stile tramite il linguaggio
CSS3.

Similmente se si ricerca un determinato hotel inserendo nel form ricerca una qualunque parola
contenuta in ogni attributo degli hotel presenti in database questo apparirà nella pagina di ricerca.
Come si può osservare dalla figura precedente solo poche righe di codice sono differenti, nel primo if
statement si verifica che il pulsante di ricerca sia stato premuto, è cambiato l’url da inviare tramite la
funzione curl, poi si effettua un controllo per verificare se il risultato è vuoto in quanto l’utente può
eseguire la ricerca senza inserire nessun carattere nel form relativo alla ricerca, infine, si crea un link che
porta alla pagina relativa agli hotel ricercati.
Per esempio inserendo la parola colazione e premendo il pulsante di ricerca, si hanno i seguenti
risultati:

Come possiamo vedere viene riportato il numero di risultati trovati e di seguito i link che riporta alla pagina
dei singoli hotel.
Design Patterns

Quali sono stati I problemi che abbiamo incontrato?

All’interno dell’applicazione è necessaria un’unica istanza dell’oggetto della classe db. Per raggiungere
questo scopo è stato utilizzato il singleton pattern, il quale permette di restringere l’istanziazione di una
classe ad un singolo oggetto. Di seguito è riportato il diagramma delle classi del pattern.

Come si vede dalla Figura, il costruttore della classe è privato. L’unico modo per ottenere l’istanza della
classe è tramite il metodo pubblico e statico getInstance().
A singleton should be used when managing access to a resource which is shared by the entire application,
and it would be destructive to potentially have multiple instances of the same class. Making sure that
access to shared resources thread safe is one very good example of where this kind of pattern can be vital.
When using Singletons, you should make sure that you're not accidentally concealing dependencies. Ideally,
the singletons (like most static variables in an application) be set up during the execution of your
initialization code for the application (static void Main() for C# executables, static void main() for java
executables) and then passed in to all other classes that are instantiated which require it. This helps you
maintain testability.
As everyone has said, a shared resource - specifically something that cannot handle concurrent access.
Shared resources. Especially in PHP, a database class, a template class, and a global variable depot class. All
have to be shared by all modules/classes that are being used throughout the code.

Posso utilizzare la funzione get instance in quanto è public e mi restituisce un’instanza dell’oggetto che se è
già stata create precedentemente me la restituisce senza creare una nuova istanza (per questo si utilizza
una variabile statica e si fa il controllo tramite l’if statement).

The Front Controller pattern is a software design pattern listed in several pattern catalogs. The pattern
relates to the design of web applications. It "provides a centralized entry point for handling requests."
It handles all incoming requests and brings them to the right place/controller.
L'alternativa al modello Front Controller è la creazione di script individuali, per
esempio login.php e order.php che gestiscano le varie tipologie di richieste. In questa modalità ogni script
dovrebbe duplicare il codice o gli oggetti comuni a tutte le operazioni