Slide dall'Università su REST in PHP. Il Pdf illustra il paradigma REST e i Web Services RESTful, con esempi pratici in PHP. Questo documento di Informatica per l'Università fornisce una guida passo-passo per l'implementazione di servizi RESTful, includendo l'uso di .htaccess e la configurazione di Apache.
Ver más24 páginas
Visualiza gratis el PDF completo
Regístrate para acceder al documento completo y transformarlo con la IA.
Il paradigma REST
• REST = Representational State Transfer
- È un paradigma generico, non esclusivamente o
necessariamente relativo ai Web Services
• Principio base: stato dell'applicazione e
funzionalità sono rappresentati da risorse,
accessibili tramite identificatori univoci (URI)
Le funzionalità di un web service sono
•
rappresentate da risorse identificate da URI
diverse
- Es. http://www.motore.com/cerca/web/,
http://www.motore.com/cerca/immagini/
• E' necessario specificare anche
- Il tipo MIME dei dati scambiati (es text/xml)
- Le operazioni supportate tramite i metodi di HTTP
POST, GET, PUT e DELETE.
• REST sfrutta il significato specificato per i
metodi di HTTP più di quanto si faccia
regolarmente:
- Creare una risorsa sul server: POST
- Reperire: GET
- Cambiare lo stato di una risorsa o modificarla: PUT
- Rimuovere o cancellare: DELETE.
Il risultato dell'invocazione
•
puo essere qualsiasi risorsa,
…
• Ma tipicamente sarà XML o JSON, con un
contenuto da interpretare a cura del client
- Nel caso di XML non esiste, in linea di massima, una
libreria che serializza/deserializza in modo standard
• JSON: Javascript Object Notation
- Formato (standard) di scambio dati basato su un
subset di Javascript
o È una serializzazione di variabili e liste ordinate
o Esistono librerie per la sua interpretazione in ogni linguaggio
• In Javascript si tratta semplicemente di fare un eval()
• Anche se basato su Javascript, è indipendente dal
linguaggio di programmazione
-
E comprensibile a chiunque programmi
• Due strutture per rappresentare le strutture dati che
tutti i linguaggi prevedono:
- object: insieme di coppie nome/valore
o oggetto, record, struct, dizionario, tabella hash, array associativo ...
-
array: elenco ordinato di valori
o array, vettore, ...
-
I valori possono essere stringhe, numeri, booleani, null, e di
nuovo object o array
var employees = { "accounting" : [
// accounting is an array in employees.
{ "firstName":
" John", // First element
"lastName'
"Doe",
"age"
23 },
{ "firstName"
:
"Mary",
// Second Element
"lastName"
:
"Smith",
"age"
: 32 }
], // End "accounting" array.
: [ // Sales is another array in employees.
{ "firstName"
: "Sally", // First Element
"lastName"
"sales"
: "Green" ,|
"age"
27 } ,
{ "firstName"
"Jim",
// Second Element
"lastName"
: "Galley",
"age"
: 41 }
] // End "sales" Array.
} / End Employees
• string $codificato = json_encode($variabile)
• $variabile = json_decode($testo);
• Si identificano le risorse da descrivere (es. cliente,
ordine, spedizione)
• Si mappano su uri comprensibili
- Es. www.compraplastica.it/ordine/
- I metodi di HTTP corrispondono direttamente alle
operazioni da compiere sulle risorse
-
... con parametri passati sull'uri
- Es. per creare un ordine: un POST su
www.compraplastica.it/ordine/oggetto/?id=654
• Il risultato viene interpretato dal client (di fatto è come il
document style di SOAP)
$vettore=array(
'primo'=> 1,
'secondo'=>array('a','b','c'),
'terzo'=>"ultimo della lista",
);
$json=json_encode($vettore);
print("
In");
print($json);
//Output: {"primo":1,"secondo":["a","b","c"],"terzo":"ultimo della lista"}
$nuovo=json_decode ($json) ;
var_dump ($nuovo) ;
?>Esempio 2 in PHP: requestor
• Usiamo questo servizio:
• http://currencies.apps.grandtrunk.net
- Non restituisce JSON ma testo puro
$endpoint='http://currencies.apps.grandtrunk.net/get
latest/';
$risultato=file_get_contents($endpoint."EUR/GBP");
print_r($risultato);
?>Esempio 2, altra chiamata
$listavalute= file_get_contents(
'http://currencies.apps.grandtrunk.net/currencies');
print_r($listavalute);
?>
NB: sostituire file_get_contents() con file(), cosa
cambia?REST vs. SOAP
• JSON: Più leggero ("fat free XML")
• REST: sfrutta la semantica dei metodi di HTTP, che in
SOAP di solito viene ricreata (es .. newOrder(cliente,
pezzo, quantita) )
-
Ma maggiore varietà semantica possibile
• REST: sicurezza basata su quella di HTTP
• SOAP: più standardizzato ed inserito in un sistema di
standard per discovery, ecc
• SOAP: gestisce gli attachments
• SOAP: in REST, no contratto formale (dipendenza da
documentazione scritta)REST: riassunto pratico
• Sistema informativo aziendale (semplificato),
gestisce:
Clienti
Magazzino
Ordini
Fatture
Campo | Tipo | Campo | Tipo | Campo | Tipo | Campo | Tipo |
---|---|---|---|---|---|---|---|
id | int(11) | id | int(11) | chỉ | int(11) | quando | date |
cognome | varchar(40) | descrizione | varchar(255) | cosa | int(11) | ordine | int(11) |
azienda | varchar(40) | prezzo | float | quanti | int(11) | ch | int(11) |
quando | date | totale | float | ||||
cap | varchar(5) | sconto | int(11) | ||||
citta | varchar(30) | azienda | clienti | fatture | magazzino | ordini | |
id | int(11) | id | int(11) | ||||
nome | varchar(40) | nome | varchar(200) | ||||
indirizzo | varchar(100) | quantita | int(11) | ||||
disponibile | date |
• Le solite:
CRUD (Create, Read, Update, Delete)
• Nello specifico:
- Creazione, ricerca e cancellazione di clienti
- Creazione, aggiornamento quantità, verifica
disponibilità di pezzi in magazzino
- Creazione ordini
- Creazione fatture
-
• Idealmente:
• www.azienda.it/cliente/123
- È il cliente 123, di cui leggere i dati (con GET), o
modificarli (con PUT), o cancellarlo (con DELETE)
-
... mentre un POST dei dati a
www.azienda.it/cliente/ permette di crearne uno
nuovo
• Similmente per www.azienda.it/magazzino/ e
www.azienda.it/ordine/
• Gestione metodi "inusuali" (PUT e DELETE)
- Come verificare il funzionamento di metodi http
non gestiti dai browser?
• URL significative
-
... ovviamente non sarà tutto statico
• Risposte significative
• Contenuto della risposta: (XML) o JSON
• Il metodo DELETE, ed a volte il metodo PUT, non
sono sempre configurati per default
• In caso di necessità, nei .conf di Apache:
<Directory /var/www/html/azienda >
<LimitExcept GET POST PUT DELETE HEAD OPTIONS>
Order deny,allow
Deny from all
</LimitExcept>
</Directory>
•
Il metodo utilizzato per l'invio si trova in
$_SERVER['REQUEST_METHOD']
• Nel caso di PUT, è possibile inviare coppie
variabile-valore esattamente come in GET e POST,
- Solo che PHP non definisce $_PUT
- È necessario fare un parsing del corpo della richiesta:
- $_PUT = array();
parse_str(file_get_contents('php://input'), $_PUT);
o php://input è lo stream connesso al body della richiesta
o parse_str ne interpreta il contenuto
print("
");");
var_dump($_SERVER['REQUEST_METHOD']);
var_dump($_SERVER['REQUEST_URI']);
var_dump($_SERVER['QUERY_STRING']);
print("
Comando shell
•
curl -X PUT
http://bla -d "par1=val1"
- - X metodo
- - d coppie di parametri/valori per POST/PUT
- - H [HEADER] Set a header.
• Es. curl -X PUT
http://xxxxxxxxxx/azienda/metodo.php -d
"parl=vall" -d "par2=val2"
- Cambiare il metodo con DELETE
• Websniffer.cc, testuri.org anche altri disponibili
•
In Apache sfruttiamo un modulo (mod_rewrite) che
"riscrive" gli URL arrivati verso URL specifici (che
rimangono nascosti)
- Tipo redirezione, ma di solito non è visibile come redirezione
o Più o meno è ciò che mappa ~vdm in /home/vdm/public_html
o Usa la sintassi delle espressioni regolari
•
Complicato!
-
The Apache module mod_rewrite is a killer one, i.e. it is a really sophisticated module
which provides a powerful way to do URL manipulations. ( ... ) The price you have to
pay is to accept complexity, because mod rewrite's major drawback is that it is not
easy to understand and use for the beginner. ( ... ). In other words: With mod_rewrite
you either shoot yourself in the foot the first time and never use it again or
love it for the rest of your life because of its power.
•
. htaccess per convenzione è un file
nascosto che Apache considera per impostare
localmente (nella dir dove compare) delle
direttive come quelle che compaiono nei file di
configurazione (e stessa sintassi)
- Anche se non tutte possono essere settate
localmente!
- possiamo impostare alcune misure di sicurezza,
- disabilitare la visione del contenuto della dir in
mancanza di un file index, e ...
-
Impostare anche la riscrittura di URL
•
Nel nostro caso, decidiamo che tutte le richieste
che arrivano al web service nella forma ideale
prevista prima (es. cliente/133, ordine/1234, ... )
debbano essere ricondotte sempre a:
• service.php,
- A cui passiamo sull'URL la risorsa con un parametro
res (es ?res=cliente) e l'identificatore con un
parametro id (es &id=133 )
• (solo per debugging)
• Creiamo una dir azienda, e dentro mettiamo
questo file
var_dump($_SERVER['REQUEST_METHOD']);
var_dump($_SERVER['REQUEST_URI']);
var_dump($_SERVER['QUERY_STRING']);
echo "<h2>Risorsa: ". $_GET['res']. "</h2>";
echo "<h3>ID: " .$_GET['id'] ."</h3>";
?>
RewriteEngine on
RewriteRule ^cliente/(\w+)/?$ /azienda/service.php?res=cliente&id=$1 [L]
RewriteRule ^magazzino/(\w+)/?$ /azienda/service.php?res=magazzino&id=$1 [L]
RewriteRule ^ordine/(\w+)/?$ /azienda/service.php?res=ordine&id=$1 [L]
Descrizione dell'URL da sostituire con espressioni regolari
https://regex101.com
URL destinazione, dalla radice di DocumentRoot
• sudo a2enmod rewrite
• sudo nano /etc/apache2/sites-
enabled/000-default.conf
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
•
sudo apache2ctl restart
• apache2ctl configtest
• Da browser, proviamo ad andare alla pagina
•
http://Xxx
xxx.xx/azienda/cliente/ 13
- Cosa succede?
- Proviamo anche le URL simili per magazzino e ordine
• Ora proviamo a simulare l'URL che dovrebbe
creare un nuovo cliente, se richiamata con POST:
• http://Xxx.x
.xxx.xx /azienda/cliente/
- Cosa succede?