(Lee esta receta en español pulsando sobre la bandera )
With this recipe we intend to introduce you to the wonderful world of Web APIs. Nowadays, consulting certain information from a remote server or the process of exchanging data between different servers is commonly done using Web APIs. Practically every Web apps and mobile applications that we use every day have e a Web API in their backend to implement their functionalities, from adding and saving products in the shopping cart in Amazon, to consult the map of your city. Web APIs are a fundamental mechanism to allow different software running on the same or different platforms to communicate with each other.
At the end of this recipe you will be able to:
Understand the concepts of Web API and Web Service.
Distinguish the main differences between a SOAP Web Services and REST Web Services.
Contrast the design principles of a Web API of type REST against the RPCs.
Know the advantages of Web programming using frameworks.
Design and develop your own API REST in Python.
Before going into depth in the design and development of your Web API we must make a brief introduction to what is and what consists of a Web Service.
Web Services are essentially connection points that allow the integration between applications hosted on platforms that may be different (or not), run different operating systems and be implemented in different programming languages. Web services communicate with each other through the WWW and require two parts:
A server part that exposes a series of Web APIs.
And a second client part that invokes/consumes requests from these Web APIs hosted on the server.
Web services are independent of the implementation in the client side, which can be a Web browser, a mobile application or a desktop application capable of making calls to a number of Web APIs. Web services can be classified according to the communication protocols used:
SOAP (Simple Object Access Protocol).
HTTP REST (Representation State Transfer).
Service-Oriented Architecture (SOA). Main types.
SOAP services work over HTTP, FTP, POP3, TCP, messaging queues (JMS, MQ, etc.), although they are usually invoked over HTTP protocol. Another special feature of SOAP services is that they only allow the exchange of data using the XML metal language.
On the other hand, REST-type services transport data only via the HTTP protocol, but allow the use of various methods provided by HTTP for communication (GET, POST, PUT, PATCH, DELETE) and, at the same time, they use the native HTTP response codes (404, 200, 204, 409).
REST is more flexible than SOAP and allows us to transmit various types of data (not only XML). The type of data is defined by the HTTP Content-Type header, enabling exchanges of XML, JSON, binary data, plain text, and so on. Based on this, the formats of exchange most frequently used by (REST) Web services are:
JSON (Javascript Object Notation) -> Not available in SOAP services.
XML (eXtensible Markup Language).
In this recipe we will focus on REST Web APIs (HTTP), learning to develop a set of RESTful services (that respect the REST architecture) using the Python language. Web APIs such as REST (or REST APIs) have achieved great popularity in the development community becoming the predominant architecture for designing and implementing Web services.
Web services make up the basic operating core of Web applications. Web APIs are the mechanisms of integration between these Web services, being deployed on applications of the same or other servers / services and, in turn, they can act as clients consuming information from other Web APIs.
It is required that the implementation of Web services is scalable, at the same time that the services provide an adequate and reliable operation.
REST Architecture
The REST architecture is designed based on the HTTP protocol using resources (called URIs - Uniform Resource Identifiers) and a reduced set of verbs corresponding to HTTP methods (GET, POST, PUT, PATCH, DELETE). This approach differs significantly from the one adopted by other machine-to-machine communication mechanisms for remote code execution, such as RPCs (Remote Procedure Calls), which emphasize the use of a wide variety of operations/verbs. For example, an RPC-based application could define operations as follows to manage a set of users and their locations:
Client applications consume resources using standard HTTP methods, such as GET to download a copy of a particular resource. POST is usually utilized for side-effect actions such as sending a purchase order or adding new resources to a collection.
Using the same example, a user could be represented as the resource below, where the data for this particular case is formatted in XML.
To update this user's location, a REST API client application could first download the previous XML record using GET. Then, it would modify the record to change the location and, finally, upload it to the server using the PUT method.
At this point, it should be noted that HTTP methods/verbs do not provide standard mechanisms for discovering resources, i.e. there is no LIST or FIND operation in HTTP similar to the list*() and find*() operations of the previous RPC example. Instead, REST APIs solve this problem by treating a collection of search results as another type of resource, which requires knowing the additional URLs to display or search for each particular resource type.
To deploy the API REST we are going to use a micro framework written in Python called Flask, conceived to facilitate the development of Web applications under the MVC (Model-View-Controller) pattern in a simple way (with a learning curve smaller than other major frameworks such as Django) and using a minimum number of modules/extensions/plugins (not full-stack).
In case you are a little clueless about what a framework is, what it is used for or what advantages it provides, we'll give you a few key points:
In the modern Web development different frameworks are used. They are tools that provide a working scheme (generally based on the MVC pattern) and a series of utilities and functions to facilitate and abstract low-level tasks during the development of dynamic Web pages.
These frameworks are associated to a programming language: Symphony (PHP), Ruby on Rails (Ruby), Django (Python) or in this particular case, Flask (Python).
The project associated to the Web application maintains a homogeneous structure (same elements, same files).
Facilitates collaboration between developers and designers.
Easy to find plugins and other libraries adapted to the framework used.
Particular advantages of using Flask:
It starts from a minimum development with the essential modules/extensions (not full-stack. New functionalities are added as needed).
Includes a development Web server (no extenal infrastructure with a Web server is needed for testing before deployment).
Debugger included and support for unit tests.
Efficient route management. Determine which route is requested by the client to execute the necessary code.
Native support for the use of secure cookies.
Open Source.
Abundant documentation.
After this brief walk to highlight the virtues of frameworks for Web development and after pointing out some of the positive aspects of Flask, finally, let's move to action...
We are going to design and implement a Web service for user management, which is undoubtedly a necessary requirement in the context of using any Web application or mobile client with cloud services.
The first thing is to model the resource associated with a "user". Since this is a conceptual example, we will only consider the following attributes in this first part of this recipe:
* id: Unique identifier for the user.
* username: The user name utilized in the Web application, mobile app, etc.
* email: The user's e-mail account for notification tasks.
* status/active: For example, to know if the user is online/offline.
The design of an API REST implies identifying the URI resources and the associated verbs (HTTP methods) that intervene to model the "user" resource. Actions such as: creating a new user, updating attributes of an existing user, getting information from a specific user, listing all users or deleting a specific user are required. Therefore, it is necessary to relate the previous actions with the HTTP methods (GET, POST, PUT, PATCH, DELETE), defining the CRUD operations (Create, Read, Update, Delete) for our "user" model. The following table illustrates this visually:
URI
HTTP method
Action
/v1/usuarios/
GET
Get a list of all users
/v1/usuarios/
POST
Create a new user
/v1/usuarios/1
GET
Obtain information from an existing user whose identifier is 1
/v1/usuarios/1
PUT/DELETE
Update or remove the user whose identifier is 1
To start with the implementation of the service we will first configure a virtual environment with the virtualenv tool. A virtual environment allows us to create an isolated working configuration with a specific Python interpreter (we can choose a specific version), along with a series of Python modules that we consider appropriate. You can have several different environments on the same machine, installing the necessary modules without affecting each other in each environment. Using a virtual environment avoids contaminating or filling with "rubbish" the global installation of Python and the conflicts of different versions of the same module between applications, as well as other problems related to permissions. We can install the virtualenv tool with the package manager in Linux distributions or more generally with the tool pip:
$ pip install virtualenv
virtualenv saves each virtual environment in a directory with the name of that environment. To create it we execute:
$ virtualenv VIRTUAL-ENVIRONMENT-DIRECTORY
For example:
$ virtualenv /home/gilmour/environmentVirtual1
Once installed virtualenv, it is activated executing the activate script inside the bin directory of the virtual environment:
If you look at the installation log shown in the terminal you can see that Flask is installed together with Jinja2, a template engine written in Python which allows you to insert processed data (context) as default text inside the HTML files/templates that make up the View of the MVC pattern.
Also installed is Werkzeug , a collection of various utilities for WSGI (Web Server Gateway Interface) applications based on which Flask runs. WSGI establishes a convention for Web servers about how to handle requests and redirect responses to Web applications and frameworks written in Python. Among other utilities, it includes a debugger, a session and cookies handler, a URL routing system, a utility to manage file uploads, tools to control cache options, so that the browser can be specified the caching policies to follow, both for client requests and server responses. Specifically, for caching, Werkzeug uses the parameters specified in the HTTP headers of cache-control and the HTTP Entity Tags (Etag).
Werkzeug is independent of the template engine used, the adapter for the database, etc. It does not specify or force a certain way of handling customer requests and leaves this completely in the hands of the developer.
With Flask installed and configured in our virtual environment we can implement our first small Web application in Flask that we will call applicacion.py (save the file in the root of the virtual environment directory). The code you have to include is the following:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hello I'm your first Web Flask app"
if __name__ == '__main__':
app.run(debug=True)
When running python aplicacion.py you can see how the Flask server is deployed and it is listening on port 5000 (default):
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 439-951-258
If you access the URL http://127.0.0.1:5000 you will see the result expected as a response to the HTTP GET request with the path('/'):
All right, let's go further to implement the REST API. Let's start with the HTTP GET request to retrieve all users. The URI associated to that resource is /v1/users. We need to implement a route for the URI that will trigger the execution of the function getUsuarios(). This function will return all users in JSON format from a structure that is a combination of Lists and Dictionaries in Python. Our script is as follows:
If we relaunch the application with python aplicacion.py it is now possible to make a HTTP GET request to /v1/users using the same browser as shown in the image below. We have just implemented a part of the API REST of our user management Web service.
If we inspect the request with the developer tool of the browser we can see:
The Content-Type is application/JSON.
The server is Werkzeug (Flask is based on Werkzeug).
The GET request was correct so the code 200 is returned.
...
We'll continue with another resource to get a user from his/her identifier (id). We add the following route to our script:
#...
from flask import abort
from flask import make_response
With the previously defined route we invoke the function getUsuario(id) passing as argument the identifier of the user from whom we want to obtain information. When we perform the HTTP GET request in the previous URI, internally, we iterate over the users until the one with the identifier we are looking for is located. If the user is found, the information is returned in JSON format. If not, the server sends a HTTP 404 response. If we invoke with the URL http://127.0.0.1:5000/v1/usuarios/4 we will obtain the HTTP 404 error response for the data of the example.
To be able to manage user registrations in a future client application (e.g.., Web application, mobile application, etc.) we require a new route to create users using the HTTP POST method. We add the following code in our script:
#...
from flask import request
@app.route('/v1/users/', methods=['POST'])
def createUser():
if not request.json or not 'email' in request.json:
abort(404)
id = users[-1].get('id') + 1
username = request.json.get('username')
email = request.json.get('email')
active = False
user = {'id': id, 'username': username, 'email': email, 'active': active}
users.append(user)
return jsonify({'user':user}),201
For example, we can use the curl command in Linux to test the POST request passing the necessary information of the new user in JSON format. Below is an example.
Finally, it is required the resource to delete a certain user through his/her identifier. Adding the following route in the application.py script:
#...
@app.route('/v1/users/<int:id>/', methods=['DELETE'])
def deleteUser(id):
user = [user for user in users if user['id'] == id]
users.remove(user[0])
return jsonify({}), 204 # No content
If we execute the curl statement, a HTTP request to delete the user with id=3 is performed:
We will continue working on REST APIs and Web services in future recipes.
(Read this recipe in English by clicking on the flag )
Con esta receta pretendemos introducirte en el maravilloso mundo de las Web APIs. Hoy en día, consultar determinada información de un servidor remoto o el propio proceso de intercambio de datos entre diferentes servidores se realiza comúnmente empleando Web APIs. Prácticamente la totalidad de las Web apps y aplicaciones móviles que usas cada día utiliza una Web API en su backend para implementar sus funcionalidades, desde añadir y guardar productos en el carrito de compra en Amazon, hasta consultar el mapa de tu ciudad. Las Web APIs son un mecanismo fundamental para permitir que diferente software corriendo en la misma o en plataformas distintas pueda comunicarse entre sí.
Al final de esta receta serás capaz de:
Comprender los conceptos de Web API y Web Service.
Distinguir las principales diferencias entre un Web Service de tipo SOAP y de tipo REST.
Contrastar los principios de diseño de una Web API de tipo REST frente a las RPCs.
Ventajas de la programación Web usando frameworks.
Diseñar y desarrollar tu propia API REST en Python.
Antes de entrar en profundidad en el diseño y desarrollo de tu Web API debemos hacer un inciso para introducir qué es y en qué consiste un Web Service.
Los Web Services, o servicios Web, son esencialmente puntos de conexión que permiten la integración entre aplicaciones alojadas en plataformas que pueden ser distintas (o no), correr diferentes sistemas operativos y estar implementadas en diferentes lenguajes de programación. Los servicios Web se comunican entre sí a través de la WWW y requieren dos partes:
Una parte (servidor) que pone al descubierto una serie de Web APIs.
Y una segunda parte (cliente) que invoca/consume peticiones de estas Web APIs alojadas en el servidor.
Los servicios Web son independientes de la implementación de la parte cliente, que puede ser un navegador Web, una aplicación móvil o una aplicación de escritorio capaz de hacer llamadas a una/varias Web APIs. Los servicios Web se pueden clasificar atendiendo a los protocolos de comunicación utilizados:
SOAP (Simple Object Access Protocol).
HTTP REST (Representation State Transfer).
Arquitectura Orientada a Servicios (SOA). Tipos principales.
Los servicios de tipo SOAP funcionan sobre protocolos HTTP, FTP, POP3, TCP, colas de mensajería (JMS, MQ, etc.), si bien, normalmente se invocan sobre protocolo HTTP. Otra particularidad de los servicios SOAP es que sólo permiten el intercambio de datos empleando el metalenguaje XML.
Por su parte, los servicios de tipo REST transportan datos únicamente por medio del protocolo HTTP, pero permiten utilizar los diversos métodos que proporciona HTTP para comunicarse (GET, POST, PUT, PATCH, DELETE) y a la vez, utilizan los códigos de respuesta nativos de HTTP (404, 200, 204, 409). REST es más flexible que SOAP y permite transmitir varios tipo de datos (no sólo XML). El tipo de datos está definido por la cabecera de HTTP Content-Type, lo que nos permite intercambiar, XML, JSON, datos binarios, texto plano, etc. En base a esto, los formatos de los mensajes de intercambio usados con más frecuencia por los servicios Web son:
JSON (Javascript Object Notation) -> No disponible en los servicios SOAP.
XML (eXtensible Markup Language).
En esta práctica nos centraremos en las Web APIs de tipo (HTTP) REST, aprendiendo a desarrollar un conjunto de servicios RESTful (que respetan la arquitectura REST) empleando el lenguaje Python. Las Web APIs de tipo REST (o REST APIs) han conseguido una gran popularidad en la comunidad de desarrollo convirtiéndose en la arquitectura predominante para diseñar e implementar servicios Web.
Los servicios Web componen el núcleo básico de funcionamiento de las aplicaciones Web. Las Web APIs son los mecanismos de integración entre dichos servicios Web, estando desplegadas sobre aplicaciones del mismo o de otros servidores/servicios; y a su vez pudiendo éstos actuar como clientes consumiendo información de otras Web APIs.
Se requiere que la implementación de servicios Web sea escalable, al tiempo que los servicios proporcionan un funcionamiento adecuado y fiable.
Arquitectura REST
La arquitectura REST está pensada para ajustarse al protocolo HTTP empleando sustantivos/recursos (denominados URIs - Identificador de Recursos Uniforme) y un conjunto reducido de verbos que se corresponde con los métodos de HTTP (GET, POST, PUT, PATCH, DELETE). Este enfoque difiere notablemente del adoptado por otros mecanismos de comunicación entre máquinas para la ejecución de código remoto, como es el caso de las RPCs (Remote Procedure Calls - Llamadas a Procedimientos Remotos) que ponen énfasis en la diversidad de operaciones (verbos) del protocolo. Por ejemplo, una aplicación basada en RPC podría definir operaciones como las expuestas a continuación para gestionar un conjunto de usuarios y localizaciones/ubicaciones:
Las aplicaciones cliente consumen los recursos mediante los métodos estándar de HTTP, como GET para descargar una copia de un recurso en particular. POST se utiliza, por lo general, para acciones con efectos laterales, como enviar una orden de compra o añadir nuevos recursos a una colección.
Partiendo del mismo ejemplo, un usuario podría representarse como el recurso expuesto abajo. Donde los datos, para este caso particular, están en formateados en XML.
Para actualizar la localización de este usuario, una aplicación cliente de la API REST podría primero descargar el registro XML anterior usando GET. Después, modificaría el registro para cambiar la localización y lo subiría al servidor utilizando el método PUT.
En este punto, cabe señalar que los métodos/verbos HTTP no proporcionan mecanismos estándar para descubrir recursos, es decir, no hay ninguna operación LIST o FIND en HTTP similar a las operaciones list*() y find*() del ejemplo RPC anterior. En su lugar, las APIs de tipo REST resuelven este problema tratando una colección de resultados de búsqueda como otro tipo de recurso, lo que requiere conocer las URLs adicionales para mostrar o buscar cada tipo de recurso concreto.
Para desplegar la API REST vamos a usar un micro framework escrito en Python denominado Flask, concebido para facilitar el desarrollo de aplicaciones web bajo el patrón MVC (Modelo-Vista-Controlador) de manera sencilla (con una curva de aprendizaje mucho menor que la de otros frameworks mayores como Django) y empleando un número de módulos/extensiones/plugins mínimo (no full-stack).
Por si te encuentras un poco despistado sobre qué es un framework, para qué se usa o qué ventajas proporciona te damos unas breves nociones:
En el desarrollo moderno de aplicaciones Web se utilizan diferentes frameworks que son herramientas que ofrecen un esquema de trabajo (generalmente basado en el
patrón MVC) y una serie de utilidades y funciones para facilitar y abstraer de tareas de bajo nivel en la construcción de páginas web dinámicas.
Estos frameworks están asociados a un lenguaje de programación: Symphony (PHP), Ruby on Rails (Ruby), Django (Python) o en el caso que nos ocupa, Flask (Python).
El proyecto asociado a la aplicación Web mantiene una estructura homogénea (mismos elementos, mismos ficheros).
Facilita la colaboración entre desarrolladores y diseñadores.
Fácil encontrar plugins y otras librerías adaptadas al framework usado.
Ventajas particulares de usar Flask:
Se parte de un desarrollo mínimo con los módulos/extensiones esenciales (no full-stack, si requieres nuevas funcionalidades se van añadiendo según se necesiten).
Incluye un servidor web de desarrollo (no se necesita una infraestructura con un servidor web para las pruebas antes del despliegue).
Depurador incluido y soporte para pruebas unitarias.
Gestión de rutas eficiente. Determinar que ruta está solicitando el cliente a través de su petición para ejecutar el codigo necesario.
Soporte nativo para el uso de cookies seguras.
Open Source.
Documentación abundante.
Tras este breve paseo para remarcar las virtudes de los frameworks destinados al desarrollo Web y tras señalar algunas de las virtudes de Flask, por fin, vamos a pasar a la acción...
Vamos a diseñar e implementar un servicio Web para la gestión de usuarios, que es sin duda un requisito necesario en el contexto de uso de cualquier aplicación Web o cliente móvil con servicios en la Nube.
Lo primero es modelar el recurso asociado a un "usuario". Al tratarse de un ejemplo conceptual sólo vamos a considerar los siguientes atributos en esta primera parte de la receta:
* id: Identificador único para el usuario.
* nombreUsuario: El nombre de usuario usado en la aplicación Web, móvil, etc.
* email: La cuenta de e-mail del usuario para tareas de notificación.
* status/activo: Por ejemplo, para conocer si el usuario está online/offline.
El diseño de una API REST implica identificar los recursos URIs y los verbos (métodos HTTP) asociados que intervienen para modelar el recurso de tipo "usuario". Se requieren acciones como: crear un nuevo usuario, actualizar atributos de un usuario existente, obtener la información de un determinado usuario, listar todos los usuarios o borrar un usuario determinado. Por tanto, hay que relacionar las acciones anteriores con los métodos HTTP (GET, POST, PUT, PATCH, DELETE), definiendo las operaciones CRUD (Create, Read, Update, Delete) para nuestro modelo de "usuario". La tabla siguiente ilustra esto de manera visual:
URI
Método HTTP
Acción
/v1/usuarios/
GET
Obtener una lista de todos los usuarios
/v1/usuarios/
POST
Crear un nuevo usuario
/v1/usuarios/1
GET
Obtener la información de un usuario existente cuyo identificador es 1
/v1/usuarios/1
PUT/DELETE
Actualizar o eliminar el usuario cuyo identificador es 1
Para comenzar con la implementación del servicio primero vamos a configurar un entorno virtual con la herramienta virtualenv. Un entorno virtual nos permite crear una configuración aislada de trabajo con un determinado intérprete Python (podemos elegir una versión concreta), junto con una serie de módulos de Python que consideremos oportuno. Se pueden tener varios entornos distintos en la misma máquina, instalando en cada entorno los módulos necesarios sin que unos afecten a los otros. Usar un entorno virtual evita contaminar o llenar de basura la instalación global de Python y los conflictos de diferentes versiones del mismo módulo entre aplicaciones, así como otros problemas relacionados con permisos. Podemos instalar la herramienta virtualenv con el gestor de paquetes en distribuciones Linux o de manera más general con la herramienta pip:
$ pip install virtualenv
virtualenv guarda cada entorno virtual en un directorio con el nombre de ese entorno. Para crearlo ejecutamos:
$ virtualenv DIRECTORIO-DEL-ENTORNO-VIRTUAL
Por ejemplo:
$ virtualenv /home/gilmour/entornoVirtual1
Una vez instalado virtualenv, se activa ejecutando el script activate dentro del
directorio bin del entorno virtual:
Si observas el registro de instalación que se muestra en la terminal puedes comprobar que Flask se instala junto con Jinja2, un motor de plantillas (templates) escrito en Python, el cual permite insertar datos procesados (contexto) como texto predeterminado dentro de los archivos/plantillas HTML que conforman la vista del patrón MVC.
También se instala Werkzeug, una colección de varias utilidades para aplicaciones WSGI (Web Server Gateway Interface) sobre la que funciona Flask. WSGI establece una convención para los servidores Web acerca de cómo manejar las peticiones y redireccionar las respuestas hacia aplicaciones Web y frameworks escritos en Python. Entre otras utilidades, incluye un debugger, un manejador de cookies y sesiones, un sistema para el enrutado (routing) de URLs, una utilidad para gestionar las subidas de archivos, herramientas para el control de las opciones de caché, de modo que se pueda especificar al navegador las políticas de caching a seguir, tanto para las peticiones de los clientes como para las respuestas del servidor. Para el caching, Werkzeug utiliza los parámetros especificados en las cabeceras HTTP de cache-control y las HTTP entity tags (Etag).
Werkzeug es independiente del motor de templates usado, del adaptador para la base de datos, etc. No especifica o fuerza una determinada manera de manejar las peticiones de los clientes y deja esto completamente en manos del desarrollador.
Con Flask instalado y configurado en nuestro entorno virtual podemos implementar nuestra primera pequeña aplicación Web en Flask que denominaremos aplicacion.py (guardar el archivo en la raíz del entorno virtual). El código que tienes que incluir es el siguiente:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hola soy tu primera app Web Flask"
if __name__ == '__main__':
app.run(debug=True)
Al ejecutar python aplicacion.py podrás comprobar como el servidor de Flask se despliega escuchando en el puerto 5000 (por defecto):
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 439-951-258
Si accedes a la URL http://127.0.0.1:5000 comprobarás que se visualiza lo esperado, fruto de la respuesta con éxito a la petición HTTP GET con la ruta('/'):
De acuerdo, vamos a avanzar un poco más para implementar la API REST. Empecemos por la petición HTTP GET para recuperar todos los usuarios. La URI asociada a ese recurso es /v1/usuarios. Necesitamos implementar una ruta para la URI que disparará la ejecución de la función getUsuarios(). Dicha función, devolverá todos los usuarios en formato JSON a partir de una estructura que es una combinación de Listas y Diccionarios en Python. Nuestro script queda de la siguiente manera:
Si relanzamos la aplicación con python aplicacion.py ahora es posible realizar una petición HTTP GET a /v1/usuarios desde el mismo navegador como se muestra en la imagen inferior. Acabamos de implementar una parte de la API REST de nuestro servicio Web de gestión de usuarios.
Si inspeccionamos la petición con la herramienta para desarrolladores del
navegador podemos ver:
El Content-Type es de tipo application/JSON.
El servidor es Werkzeug (Flask está basado en Werkzeug).
La petición GET fue correcta por lo que se devuelve el código 200.
...
Vamos a continuar con otro recurso para obtener un usuario a partir de su identificador (id). Añadimos la siguiente ruta a nuestro script:
#...
from flask import abort
from flask import make_response
@app.route('/v1/usuarios/<int:id>/', methods=['GET'])
def getUsuario(id):
for usuario in usuarios:
if usuario.get("id") == id:
return jsonify({'usuarios':usuario})
abort(404)
Definimos la respuesta para el codigo de error 404
Con la ruta definida anteriormente invocamos la función getUsuario(id) pasando como argumento el identificador del usuario del cual queremos obtener información. Cuando hacemos la petición HTTP GET en la URI anterior, internamente, se recorren todos los usuarios hasta localizar el usuario con el identificador buscado. Si es encontrado se devuelve su información en formato JSON, en caso negativo, el servidor envía una respuesta HTTP 404. Si invocamos con la URL http://127.0.0.1:5000/v1/usuarios/4 obtendremos la respuesta de error HTTP 404 para los datos del ejemplo.
Para poder gestionar altas de usuarios en una futura aplicación cliente (e.j.,
aplicación Web, aplicación móvil, etc.) requerimos una nueva ruta para crear
usuarios empleando el método HTTP POST. Añadimos el siguiente código en nuestro
script:
#...
from flask import request
@app.route('/v1/usuarios/', methods=['POST'])
def crearUsuario():
if not request.json or not 'email' in request.json:
abort(404)
id = usuarios[-1].get('id') + 1
nombreUsuario = request.json.get('nombreUsuario')
email = request.json.get('email')
activo = False
usuario = {'id': id, 'nombreUsuario': nombreUsuario, 'email': email, 'activo': activo}
usuarios.append(usuario)
return jsonify({'usuario':usuario}),201
Por ejemplo, podemos usar el comando curl en Linux para probar la petición POST pasando la información necesaria del nuevo usuario en formato JSON. Abajo se facilita un ejemplo.
Como puede comprobarse en el código de la función crearUsuario() el atributo email es obligatorio y, por defecto, los nuevos usuarios aparacen como "inactivos".
Implementemos ahora el recurso necesario para modificar información de un usuario. Añadir en el script aplicacion.py la ruta siguiente:
Te animamos a implementar esta API REST para el servicio Web de gestión de usuarios. Además, te proponemos que diseñes (e implementes) un servicio Web sencillo con otro contexto de aplicación diferente (por ejemplo, en el contexto de un aula inteligente). Puedes integrar la API REST de gestión de usuarios en el nuevo servicio, si así lo deseas.
Seguiremos trabajando sobre API REST y servicios Web en las pŕoximas publicaciones.