Usuario:ManuelRomero/ProgramacionWeb/WS/Rest
Contenido
REST
- Término introducido por [Roy Fielding] en 2000 (es uno de los principales autores de la especificación HTTP)
- Todos los recursos a los que accedemos en la web son definidos y diseccionados
- Rest define cómo se establece una interacción entre sistemas basada en un navegador web y http
REST Permite definir una interfaz web.
|
- interfaz
- Establecer los nombres para poder ofrecer nuestra aplicación y que interactúen con nosotros
- Cómo recoger los datos para poderlos interpretar.
- Cómo generar una salida para que nos la entiendas.
- web
- Red de páginas o recursos que se comunica por el protocolo http
(No es una definición, pero sí un concepto importante y una realidad).
Base de Rest
- Rest no es un estándar, es una especificación basada en estándares
- http
- Protocolo sin estado
- Verbos o acciones en la solicitud GET, POST, DELETE, UPDATE y PUSH.
- URL
- Representación de los recursos
- Tipos MIME : text/html , text/xml, text/json,...
|
El protocolo http establece en cada mensaje http un verbo o acción que encabeza la solicitud del mensaje.
Plantilla:MRM Recursos en la Web
|
- Estas acciones suelen ser comparados con las operaciones asociadas a la tecnología de base de datos,
operaciones CRUD: CREATE, READ, UPDATE, DELETE.
- Existen otra analogías como podemos ver en la tabla siguiente:
Accion | HTTP | SQL | Copy&Paste | UNIX Shell |
---|---|---|---|---|
Create | PUT | Insert | Pegar | > |
Read | GET | Select | Copiar | < |
Update | POST | Update | Pegar | >> |
Delete | DELETE | Delete | Cortar | Del / rm |
Acción HTTP SQL Copy&Paste Unix Shell Create PUT Insert Pegar > Read GET Select Copiar < Update POST Update Pegar después >> Delete DELETE Delete Cortar Del/rm
|
Por qué reescribir URL
- Para usar Rest, se suele hacer que la url que solicito sea lo que se llama amigable, es decir que no tiene porqué corresponder directamente al recurso que voy a localizar, sino que puedo establecer otro nombre más amigable para acceder a ese recurso.
- Por ejemplo si quiere acceder a una página para obtener un libro determinado
http://misitioWeb/App1/Biblioteca/libros/indesx.php?id_libro=8456
- Está claro que será más fácil ofrecer la url como
http://misitioWeb/libro/8456
- De lo que se trata es de escribir o invocar la segunda url y que realmente se ejecute la primera
En cualquier caso está práctica nos permitiría, además de esto:
- Permitir que las direcciones URL sean más amigables al usuario y los buscadores.
- Prevenir el “hot linking” o que usen tus imagenes en otros sitios.
- Esconder las direcciones web reales de tu servidor a los usuarios.
- Redirigir de forma transparente las peticiones web.
URI y URL's amigables
- Una URL es el localizador de ese recurso, por ejemplo
http://localhost/tienda/producto.php La URL es http://localhost/tienda.php El URI o recurso es producto.php Plantilla:MRM Referencias en la web
- Una URL amigable es una URL que el cliente va a escribir en el navegador, aunque no existe tal cual en el servidor, sino que el servidor realiza una traducción
http://programandolo.blogspot.com.es/2013/06/reglas-de-reescritura-parte-1.html#more
- supongamos que en nuestro proyecto tenemos la URL
http://localhost/reescritura/paginaAmigosConfianza.php&dato=pedro
- Es claro ver que a alguien le sería mas claro escribir
http://localhost/reescritura/amigo/pedro
- Para conseguir esto, lo que tendríamos que hacer es establecer una regla en el servidor de modo que traduzca una url en la otra
- Pasos a seguir
- La sobreescritura de direcciones amigables la hace el módulo rewrite' de apache
- Primero miramos a ver si tenemos ese módulo instalado
/usr/sbin/apachectl -t -D DUMP_MODULES
- Nos listará los módulos instalados. Buscamos rewrite
- En caso de no tenerlo instalado lo instalamos
sudo a2enmod rewrite
- Después reiniciamos el servicio
sudo service apache2 restart
- Hay que recordar que para que se apliquen las directivas del fichero .htaccess, debemos tener habilitada para ese directorio (o para todos) la directiva AllowOverride All
- Esto sería hacerlo para todos
<Directory /var/www> AllowOverride All </Directory>
- Esto sería hacerlo para una parte de mi directorio
<Directory /var/www/servicio_rest> AllowOverride All </Directory>
- Después de modificar un fichero de configuración, hay que rebotar el servicio
- Ahora escribimos las reglas de
RewriteEngine on RewriteBase /servicio_rest/ RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^(.+)$ index.php?url=$1 [QSA,NC,L]
- Las reglas de reescritura se deben definir en los ficheros de configuración de Apache (httpd.conf) o, en el caso que este activada la capacidad de reescritura, en un archivo .htaccess localizado en el directorio del servidor web donde se quiere que tenga efecto.
- Estamblecemos /servicio_rest como directorio base
- Las tres reglas siguiente establece que directorios (-d), ficheros (-f) y enlaces simbólicos (-l) que ya existen, sobre ellos no sea aplicada las reglas de reescritura.
- El último punto es la reescritura
En este caso tenemos la expresión regunar ^(.+)$
- Se puede leer como cualquier conjunto de caracteres al principio que contenga uno o más caracteres hasta el final
- Esta expresión regular será tomada seguida de el dominio y el directorio establecido como base, es decir después de http://localhost/servicio_rest/ .....
- Posteriormente puedo tomar su contenido en la variable $1
- Nos realiza la transformación siguiente (1) escrible el cliente, (2) lee el servidor
http://localhost/servicio_rest/productos/1 http://localhost/servicio_rest/index.php?url=productos/1
Haciendo un servicio REST
- Ahora toca la parte práctica
- Vamos a implementar un servicio web que realice una suma y resta, al igual que hicimos con soap
- Antes de ello, para probarlo haremos un ejemplo que solo en el que el servicio nos salude
- Servidor
- En el servidor lo que tenemos que hacer es recoger la solicitud que nos hacen y crear una respuesta
- La solicitud puede ser GET POST PUT DELETE
- En php podemos saber este valor de la superglobal $_SERVER
- La parte del cliente
- En este caso la parte de cliente es muy sencilla, simplemente tiene que hacer una llamada a esta página y leer su contenido
- Para esto puede valer usar la fución get_file_content
- Lógicamente en este caso estamos haciendo una solicitud GET
<?php $response = file_get_contents('http://localhost/servidor_rest/index.php'); $response = json_decode($response); echo "Saludo que viene del servidor $response"; ?>
|
La parte del cliente
- Si desde el cliente queremos realizar una invocación que no sea siempre GET, puediendo realizar invocaciones PUT, POST, .... vamos a usar la librería Curl
- Curl
Înstalamos el comando o aplicación curl
sudo apt-get install curl
- Lo primero debemos tener instalada la librería de curl para php
sudo apt-get install php5-curl
- En php7
sudo apt-get install php-curl
- La forma de realizar una solicitudes es realizando una llamada completa a la web
- Ver el contenido del fichero como hemos hecho antes, es simplemente hacer una especie RPC (Invocación o llamada a métodos remotos).
- Usar curl con php es relativamente sencillo
http://php.net/manual/es/curl.examples-basic.php
- Para usarlo seguimos los siguientes pasos:
- Inicializamos una sesión cURL usando curl_init()
- Se establecen las opciones para la transferencia con curl_setopt() (Se especifican más abajo.
- Ejecutamos la sesión curl_exec() Aquí se puede recoger el resultado
- Cerramos la sesión con curl_close()
<?php $ch = curl_init("http://www.example.com/"); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); ?> |
- Una lista de las opciones más utilizadas
- Especificar la URL
- CURLOPT_URL EL la URL donde está el recurso al que queremos acceder. También se puede establecer en el método curl_init()
$llamada = curl_init(); curl_setopt($llamada, CURLOPT_URL, "http://localhost/servicio_rest/productos);
- O bien
$llamada = curl_init("http://localhost/servicio_rest/productos);
- CURLOPT_HEADER
- Para incluir las cabeceras de las respuestas (true o false
- Normalmente lo estableceremos a false, si solo nos interesa el contendio
- Se puede establecer a false, o pasar una cadena de caracteres tipo
$llamada = curl_init(); curl_setopt($llamada, CURLOPT_HEADER, false);
- CURLOPT_RETURNTRANSFER
- Para que en lugar de mostrar la respuesta, devuelva una cadena de caracteres de tipo string
$llamada = curl_init(); curl_setopt($llamada, CURLOPT_RETURNTRANSFER, true);
- CURLOPT_POST
- Establece una solicitud post. En este caso se usa la opción siguiente para pasar datos a la solicitud
$llamada = curl_init(); curl_setopt($llamada, CURLOPT_POST, true);
- CURLOPT_POSTFIELDS
- Para pasar los datos de la solicitud POST
curl_setopt($llamada, CURLOPT_POSTFIELDS, "usuario=dwes&pass=abc123.;");
- Alternativamente podemos usar el método http_build_query (...) pasándole un array asociativo
$llamada = curl_init(); $datosPost=['usuariol'=>'dwes', password' =>'abc123.' ]; ); $llamada = curl_init(); curl_setopt($llamada, CURLOPT_URL, "http://localhost/servicios_rest/login.php"); curl_setopt($llamada, CURLOPT_POST, true); curl_setopt($llamada, CURLOPT_POSTFIELDS, http_build_query($datosPost));
- CURLOPT_CUSTOMERREQUEST
- Establece la acción solicitada al servidor cuando esta no es ni GET (por defecto) ni POST (CURL_POST). Como ya hemos comentado suele ser "DELETE"o 'PUT' u otros tipos de peticiones HTTP menos comunes.
- Para pasar datos que se necesitaran en esta solicitud, se usa igualemnte la opción CURLOPT_POSTFIELDS
$llamada = curl_init(); $datos=['producto'=>'Cod_123dwes';stock=500]; ); curl_setopt($llamada, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_setopt($lamada, CURLOPT_POSTFIELDS, http_build_query($datos)); .... $datos=['producto'=>'Cod_123dwes' curl_setopt($llamada, CURLOPT_CUSTOMREQUEST, "PUT"); curl_setopt($cllamada, CURLOPT_POSTFIELDS, http_build_query($datos))