A estas alturas ya deberías saber qué es una API REST, si no, te recomiendo leer sobre esto aquí.
A modo de breve resumen, construir una API de forma REST significa que tienes que construir sus endpoints de URL agrupados por "recursos". Un recurso es algo que quieres gestionar, por ejemplo: un estudiante, un usuario, un auto, etc. Un recurso es algo similar a una tabla de base de datos, pero los llamamos "recursos" debido a algunas excepciones.
Aquí hay un ejemplo de endpoints RESTful API para gestionar Estudiantes:
Método | URL | Descripción |
---|---|---|
GET | /estudiantes | Debería devolver todos los estudiantes |
GET | /estudiantes/1 | Debería devolver un solo estudiante con el id=1 |
GET | /cohorts/1/estudiantes | Debería devolver todos los estudiantes de la clase con el id=1 |
POST | /estudiantes | Debería crear un nuevo estudiante |
PUT | /estudiantes/1 | Debería actualizar la información del estudiante con el id=1 |
DELETE | /estudiantes/1 | Debería eliminar al estudiante con el id=1 |
Echa un vistazo a las URL, siguen un patrón. Después de un tiempo, los endpoints hablarán por sí mismos, tendrán sentido y podrás adivinar lo que hacen o incluso adivinar algunos endpoints. Esa es la idea.
👉 Puede leer más sobre las API REST en esta lección de 4Geeks.
Aquí hay un video de 8 minutos que explica REST: https://www.youtube.com/watch?v=7YcW25PHnAA
¡Flask es increíble! Es muy similar al Servidor Express Node.js y eso lo hace aún más genial porque podrás trabajar con ambas tecnologías sin mucha curva de aprendizaje.
Flask es una librería de Python para crear un servidor web y APIs. Básicamente, cuando ejecutas un script de Python que contiene las siguientes líneas, el computador comenzará a escuchar las solicitudes HTTP:
1from flask import Flask 2app = Flask(__name__) 3 4@app.route("/") 5def hello(): 6 return "Hello World!" 7 8app.run(host='0.0.0.0')
Haz clic para probar este código en vivo
1from flask import Flask # Aquí importamos la librería Flask en nuestro archivo 2app = Flask(__name__) # Aquí creamos una nueva instancia del servidor Flask 3 4@app.route("/") # Aquí definimos el primer path de la API: GET / 5def hello() # Este método se llamará cuando el cliente haga el request 6 return "Hello World!" # Aquí flask devolverá "Hello World!", esto podría ser un string HTML o un string JSON 7 8app.run(host='0.0.0.0') # Finalmente iniciamos el servidor en el localhost
En Flask podemos agregar nuevos endpoints utilizando el decorador @app.route
. No te preocupes si esta es la primera vez que ves un decorador, el concepto es muy simple y aquí hay un video de 5 minutos explicándolo.
Si deseas agregar otro endpoint a tu API que se ejecuta cuando un cliente haga el GET /person
, tendrás que agregar otro bloque de código como este:
1@app.route("/person") # Aquí especificamos la ruta para el endpoint 2def handle_person() # Aquí declaramos una función que se llamará cuando se realice una request a esa URL 3 return "Hello Person!" # Aquí especificamos el string que queremos responder al cliente
Si deseas que tu endpoint responda a POST, PUT o DELETE, puedes especificarlo en el decorador de la siguiente manera:
1from flask import Flask, request 2 3@app.route("/person", methods=['POST', 'GET']) # Aquí especificamos que este endpoint acepta solicitudes POST y GET 4def handle_person(): 5 if request.method == 'POST': # Podemos entender qué tipo de request estamos manejando usando un condicional 6 return "Se recibió un POST" 7 else: 8 return "Se recibió un GET"
La respuesta puede ser básicamente lo que quieras siempre que sea un string: HTML, JSON, CSS, imágenes, etc. Solo asegúrate de convertir en string lo que quieras responder.
En el siguiente ejemplo, estamos utilizando el método jsonify
para convertir un diccionario llamado person1
en un string JSON antes de devolverlo al cliente.
1from flask import Flask, jsonify 2 3@app.route("/person") 4def handle_person(): 5 person1 = { 6 "name": "Bob" 7 } 8 9 return jsonify(person1)
El código de respuesta es 200 por defecto, y 500 si hay un error desconocido. Si deseas responder al cliente con un código diferente, deberás especificarlo así:
1from flask import Flask, jsonify 2 3@app.route("/person") 4def handle_person(): 5 content = { 6 "details": "Hubo un error en la solicitud" 7 } 8 resp = jsonify(content) 9 resp.status_code = 400 # Aquí cambiamos el código de estado a 400 (código muy común en caso de errores de solicitud) 10 11 return resp
Otra forma de cambiar el código de respuesta usando una coma ,
:
1@app.route("/person") 2def handle_person(): 3 content = { 4 "details": "Hubo un error en la solicitud" 5 } 6 7 return jsonify(content), 400
Pero ¿y si la solicitud viene con errores? Por ejemplo: si tenemos un endpoint para crear una persona y debemos especificar el first_name
y el last_name
, pero solo se encontró el first_name
en la solicitud, así es como lo validaríamos:
1@app.route('/person', methods=['POST']) 2def create_person(): 3 # POST request 4 body = request.get_json() # Obtener el request body de la solicitud 5 if body is None: 6 return "El cuerpo de la solicitud es null", 400 7 if 'first_name' not in body: 8 return 'Debes especificar first_name', 400 9 if 'last_name' not in body: 10 return 'Debes especificar last_name', 400 11 12 return "ok", 200
Existen diversas formas de integrar Flask con un servidor de base de datos, pero en esta ocasión explicaremos la integración con SQLAlchemy.
Hay una excelente biblioteca de Python que integra Flask + SQLAlchemy de manera fluida: Flask-SQLAlchemy. Te sugerimos que leas esta lección sobre SQLAlchemy primero y luego vuelvas aquí.
Para integrar SQLAlchemy con Flask, todo lo que tienes que hacer es instalar el paquete e importarlo en tus archivos de la siguiente manera:
1from flask_sqlalchemy import SQLAlchemy 2db = SQLAlchemy()
Una vez que está importado, puedes empezar a declarar tus modelos de base de datos de esta manera:
1class Person(db.Model): 2 id = db.Column(db.Integer, primary_key=True) 3 username = db.Column(db.String(80), unique=True, nullable=False) 4 email = db.Column(db.String(120), unique=True, nullable=False) 5 6 def __repr__(self): 7 return '<Person %r>' % self.username 8 9 def serialize(self): 10 return { 11 "username": self.username, 12 "email": self.email 13 }
Puedes agregar tantos modelos como desees.
Hemos preparado una plantilla que puedes ejecutar tú mismo en GitHub Codespaces o Gitpod y utilizarlo como base para tu proyecto.
Flask Rest Hello: https://github.com/4GeeksAcademy/flask-rest-hello