De acuerdo con Wikipedia, la internet de las cosas (IoT, por sus siglas en inglés) es un concepto que se refiere a una interconexión digital de objetos cotidianos con internet. Constituye un cambio radical en la calidad de vida de las personas en la sociedad, ofreciendo nuevas oportunidades en el acceso a datos, educación, seguridad, asistencia sanitaria y en el transporte, entre otros campos. Por ejemplo, en logística y manejo de flotas, se puede hacer seguimiento en todo momento de la ubicación y las condiciones de vehículos mediante sensores inalámbricos conectados a internet que envían alertas en caso de eventualidades (demoras, daños, robos, etc.).
La IoT también plantea retos como el almacenamiento, análisis y visualización de la gran cantidad de información que genera. Se calcula que para el 2025 los dispositivos IoT generen 79.4 zettabytes (1 zettabyte equivale a 1 trillón de gigabytes). Como desarrolladoras debemos estar al tanto de estos retos y contribuir para su solución desde nuestra experiencia, conocimiento y ganas de aprender.
En este proyecto construirás la API REST de un Fleet Management Software para consultar las ubicaciones de los vehículos de una empresa de taxis en Beijing, China.
Te entregaremos las ubicaciones de casi 10 mil taxis. Esperamos que como desarrolladora explores nuevas alternativas y técnicas para almacenar y consultar esta información y puedas garantizar la mejor experiencia de usuaria en tu API REST.
Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo.
[ ] Variables (declaración, asignación, ámbito)
* [Variables in Python – Real Python (en inglés)](https://realpython.com/python-variables/) * [Variables in Python - GeeksforGeeks (en inglés)](https://www.geeksforgeeks.org/python-variables/)
[ ] Uso de condicionales (if, elif, ternario)
* [Conditional Statements in Python – Real Python (en inglés)](https://realpython.com/python-conditional-statements/)
[ ] Operadores (identidad, aritméticos, comparación etc)
* [Python Operators - GeeksforGeeks (en inglés)](https://www.geeksforgeeks.org/python-operators/)
[ ] Docstrings (y su diferencia de comentarios)
* [Docstrings - Python Docs (en inglés)](https://docs.python.org/3/tutorial/controlflow.html#documentation-strings)
[ ] Linting (pylint)
* [Pylint - Documentación oficial](https://pylint.pycqa.org/en/latest/) * [Linting Python in Visual Studio Code - Visual Studio Code Docs (en inglés)](https://code.visualstudio.com/docs/python/linting)
[ ] Serialización (y deserialización)
* [Serialize Your Data With Python – Real Python (en inglés)](https://realpython.com/python-serialize-data/)
[ ] Tipos de datos primitivos (int, float, str, bool)
* [Data Types - Python Docs (en inglés)](https://docs.python.org/3/library/datatypes.html) * [Data types in Python (en inglés)](https://www.educative.io/answers/data-types-in-python)
[ ] Listas (arrays)
* [Lists - Python Docs (en inglés)](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists) * [Lists and Tuples in Python - Real Python (en inglés)](https://realpython.com/python-lists-tuples/)
[ ] Tuples
* [Tuples - Python Docs (en inglés)](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences) * [Lists and Tuples in Python - Real Python (en inglés)](https://realpython.com/python-lists-tuples/)
[ ] Dictionaries (Dicts)
* [Dictionaries - Python Docs (en inglés)](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) * [Dictionaries in Python - Real Python (en inglés)](https://realpython.com/python-dicts/)
[ ] Sets
* [Sets - Python Docs (en inglés)](https://docs.python.org/3/tutorial/datastructures.html#sets) * [Sets in Python - Real Python (en inglés)](https://realpython.com/python-sets/)
[ ] Conceptos basicos (params, args, default values, return)
* [Python Functions - GeeksforGeeks (en ingles)](https://www.geeksforgeeks.org/python-functions/)
[ ] *args y kwargs**
* [*args and **kwargs in Python - GeeksforGeeks (en inglés)](https://www.geeksforgeeks.org/args-kwargs-python/)
[ ] Cierres (closures)
* [Closures - Python Docs (en inglés)](https://docs.python.org/3/reference/datamodel.html#emulating-closures-and-nested-scope)
[ ] Funciones lambda
* [Lambda Functions - Python Docs (en inglés)](https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions) * [How to Use Python Lambda Functions – Real Python (en inglés)](https://realpython.com/python-lambda/)
[ ] Decoradores
* [Decorators - Python Docs (en inglés)](https://docs.python.org/3/glossary.html#term-decorator) * [Decorators in Python - Geeks for Geeks (en inglés)](https://www.geeksforgeeks.org/decorators-in-python/)
[ ] Uso de bucles/ciclos (while, for..in)
* [Loops in Python - For, While and Nested Loops - GeeksforGeeks](https://www.geeksforgeeks.org/loops-in-python/) * [Loops - Learn Python - Free Interactive Python Tutorial](https://www.learnpython.org/en/Loops)
[ ] Comprensión de listas
* [List Comprehension - Python Docs (en inglés)](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) * [List Comprehension in Python - GeeksforGeeks (en inglés)](https://www.geeksforgeeks.org/list-comprehensions-in-python/) * [When to Use a List Comprehension in Python – Real Python (en inglés)](https://realpython.com/list-comprehension-python/)
[ ] Técnicas funcionales (map, filter, reduce)
* [Our Guide to Map, Filter, and Reduce Functions in Python - Udacity (en inglés)](https://www.udacity.com/blog/2020/12/our-guide-to-map-filter-and-reduce-functions-in-python.html) * [Map, Filter, Reduce - Learn Python - Free Interactive Python Tutorial (en inglés)](https://www.learnpython.org/en/Map%2C_Filter%2C_Reduce)
[ ] Pruebas unitarias (unit tests, unittest, pytest)
* [unittest - Python Docs (en inglés)](https://docs.python.org/3/library/unittest.html) * [pytest - Documentación oficial](https://docs.pytest.org/en/6.2.x/)
[ ] Uso de mocks (y patch)
* [unittest.mock - Python Docs (en inglés)](https://docs.python.org/3/library/unittest.mock.html) * [Python Mock Library - Real Python (en inglés)](https://realpython.com/python-mock-library/)
[ ] Uso de fixtures
* [pytest fixtures - Documentación oficial](https://docs.pytest.org/en/6.2.x/fixture.html)
[ ] Módulos
* [Módulos - Python Docs (en inglés)](https://docs.python.org/3/tutorial/modules.html)
[ ] Paquetes
* [Paquetes - Python Docs (en inglés)](https://docs.python.org/3/tutorial/modules.html#packages)
[ ] pip (instalación y uso de paquetes)
* [pip - Python Docs (en inglés)](https://docs.python.org/3/installing/index.html)
[ ] Virtual Environment (ambientes virtuales, virtualenv)
* [venv — Creation of virtual environments — Python 3.12.2 documentation (en inglés)](https://docs.python.org/3/library/venv.html) * [Python Virtual Environments: A Primer – Real Python (en inglés)](https://realpython.com/python-virtual-environments-a-primer/)
[ ] requirements.txt
* [requirements.txt - Documentación oficial](https://pip.pypa.io/en/stable/user_guide/#requirements-files)
[ ] Decorador de ruta
* [Routing - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/quickstart/#routing)
[ ] Función de vista
* [View Functions - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/quickstart/#view-functions)
[ ] Reglas de variables (urls dinamica)
* [Variable Rules - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/quickstart/#variable-rules)
[ ] Argumentos
* [Request - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/quickstart/#accessing-request-data)
[ ] Headers (cabeceras)
* [Request - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/quickstart/#accessing-request-data)
[ ] Partes de la respuesta (status, body, headers)
* [Response - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/quickstart/#about-responses)
[ ] jsonify
* [jsonify - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/api/#flask.json.jsonify)
[ ] Configuración de fixtures
* [Testing - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/testing/#fixtures)
[ ] Test Client
* [Testing - Flask Docs (en inglés)](https://flask.palletsprojects.com/en/3.0.x/testing/#sending-requests-with-the-test-client)
[ ] Modificadores de acesso (public, private, protected)
[ ] Variables
[ ] Uso de condicionales
[ ] Uso de bucles (Loops)
[ ] Primitivos
[ ] Datos primitivos vs no primitivos
[ ] Cadenas
[ ] Arreglos
[ ] ArrayList
[ ] HashMap
[ ] HashSet
[ ] JUnit
[ ] Mockito
[ ] Initializr
* [Spring Initializr](https://start.spring.io/)
[ ] Spring Boot
* [Spring Boot Reference Documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/)
[ ] Controladores
[ ] Servicios
[ ] Spring Data JPA
* [Spring Data JPA - Reference Documentation](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/)
[ ] Entidad
[ ] Repositorio
[ ] Beans
[ ] Inversión de Control
[ ] Anotaciones
[ ] RestController
[ ] RequestMapping
[ ] RequestParam
[ ] Spring Test
[ ] Hamcrest
[ ] Configuración
[ ] Esquema
[ ] Entidad
[ ] Tabla
[ ] Columna
[ ] Identificadores
[ ] Asociaciones
[ ] Colecciones
[ ] Persistencia
[ ] Consultas
[ ] Clases
[ ] Objetos
[ ] Métodos
[ ] Atributos
[ ] Constructores
[ ] Encapsulamiento
[ ] Abstracción
[ ] Composición
[ ] Interfaces
[ ] Herencia (super, extends, override)
[ ] Lenguaje de Modelado Unificado (UML, class diagrams)
[ ] Consulta o petición (request) y respuesta (response).
* [Generalidades del protocolo HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Overview) * [Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages)
[ ] Cabeceras (headers)
* [HTTP headers - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Headers)
[ ] Cuerpo (body)
* [Cuerpo de Mensajes HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Messages#cuerpo)
[ ] Verbos HTTP
* [Métodos de petición HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Methods)
[ ] Códigos de status de HTTP
* [Códigos de estado de respuesta HTTP - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/Status) * [The Complete Guide to Status Codes for Meaningful ReST APIs - dev.to](https://dev.to/khaosdoctor/the-complete-guide-to-status-codes-for-meaningful-rest-apis-1-5c5)
[ ] Encodings y JSON
* [Introducción a JSON - Documentación oficial](https://www.json.org/json-es.html)
[ ] CORS (Cross-Origin Resource Sharing)
* [Control de acceso HTTP (CORS) - MDN](https://developer.mozilla.org/es/docs/Web/HTTP/CORS)
[ ] JWT (JSON Web Token)
[ ] Almacenamiento y acceso de contraseñas
[ ] Operaciones CRUD (Create-Read-Update-Delete)
* [INSERT](https://www.postgresql.org/docs/9.5/sql-insert.html) * [SELECT](https://www.postgresql.org/docs/9.5/sql-select.html) * [UPDATE](https://www.postgresql.org/docs/9.1/sql-update.html) * [DELETE](https://www.postgresql.org/docs/8.1/sql-delete.html)
[ ] Modelado de datos
[ ] Conexión
[ ] Tipos de datos
* [Chapter 8. Data Types - Docs (en inglés)](https://www.postgresql.org/docs/14/datatype.html)
[ ] Índices
* [Chapter 11. Indexes - Docs (en inglés)](https://www.postgresql.org/docs/14/indexes.html)
[ ] Git: Instalación y configuración
[ ] Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)
[ ] Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)
[ ] GitHub: Creación de cuenta y repos, configuración de llaves SSH
[ ] GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)
[ ] GitHub: Organización en Github (projects | issues | labels | milestones | releases)
Nuestra cliente ha instalado dispositivos GPS en sus taxis. Estos dispositivos utilizan señales satelitales para determinar con precisión las coordenadas geográficas del taxi.
Nuestra clienta requiere:
El Product Owner nos presenta este backlog que es el resultado de su trabajo con la clienta hasta hoy y la documentación de la API REST a desarrollar.
Yo, como desarrolladora, quiero cargar la información almacenada hasta ahora en archivos sql en una base de datos PostgreSQL, para facilitar su consulta y análisis.
Yo como clienta de la API REST requiero un endpoint para listar todos los taxis.
Por ejemplo, este endpoint podria ser usado por una aplicación web para filtrar un listado de taxis.
<img src="https://github.com/Laboratoria/curriculum/assets/16993732/c4acb543-a422-4e79-ab6c-53c656a7ee47" alt="Posible uso del endpoint GET /taxis" aria-describedby="get-taxis-ui-control" />
Animación que muestra un menú desplegable para elegir un taxi. Las opciones se filtran según el text que se escriba en la lista.
plate
para retornar unicamente
los taxis cuya placa contenga el texto especificado/taxis
en la colección postman.Yo como clienta de la API REST requiero un endpoint para consultar todas las ubicaciones de un taxi dado el id y una fecha.
Por ejemplo, este endpoint podría ser usado por una aplicación web para mostrar en un mapa la trayectoria de un taxi.
<img src="https://github.com/Laboratoria/curriculum/assets/16993732/d716cc84-47c2-4cdd-8f67-74128aa6ec01" alt="Posible uso del endpoint GET /trajectories/{taxiId}" aria-describedby="get-trajectories-ui-control" />
Animación que muestra en un mapa la trayectoria de un taxi.
/trajectories
en la colección postman.Yo como clienta de la API REST requiero un endpoint para consultar la última ubicación reportada por cada taxi.
Por ejemplo, este endpoint podria ser usado por una aplicación web para mostrar en una mapa la última posición de cada taxi.
<img src="https://github.com/Laboratoria/curriculum/assets/16993732/a6bd8631-244d-4d9b-a297-2519d9313855" alt="Posible uso del endpoint GET /trajectories/latest" aria-describedby="get-latest-trajectories-ui-control" />
Animación que un listado de taxis y al hacer clic en cada uno muestra un mapa la última posición de un taxi.
/trajectories/latest
en la colección postman.Yo, como clienta de la API REST, requiero un conjunto de endpoints para poder realizar operaciones CRUD (Crear, Leer, Actualizar, Eliminar) sobre los usuarios de la plataforma.
/users
en la colección postman.Por supuesto, aquí tienes la historia de usuario para un endpoint de login que devuelve un JWT (JSON Web Token) dado un correo electrónico y contraseña válidos:
Yo, como clienta de la API REST, necesito un endpoint para poder autenticarme en la plataforma utilizando mi correo electrónico y contraseña, y recibir un JWT válido que pueda ser utilizado para acceder a recursos protegidos.
/login/auth
en la colección postman.Yo, como desarrolladora del sistema, necesito asegurarme de que todos los endpoints de la API estén protegidos utilizando un token JWT en el encabezado de autorización de cada petición, para garantizar la seguridad de los datos y recursos de la plataforma.
Puedes implementar este proyecto en JavaScript, Python o Java.
Incluido en el proyecto hay una suite de pruebas que se deben ejecutar para ver si tu API cumple con lo que espera la especificación. Debes ejecutar estas pruebas con cada historia de usuario para verificar que has completado la funcionalidad.
Las pruebas están incluidas en el directorio postman
.
Para ejecutar las pruebas, puedes usar
la extensión de Postman para Visual Studio Code,
e importar el director postman
.
Pero para ejecutar toda la colección de pruebas simultáneamente (y de forma gratuita),
necesitas instalar una herramienta de línea de comandos llamada newman
.
Sigue las instrucciones para instalar newman
globalmente. Luego puedes ejecutar la colección con el entorno incluido así:
newman run postman/collection.json -e postman/environment.json
postman/collection.json
es una colección para los endpoints del API
sin autenticación.
Si también completas las historias de usuario de autenticación del API,
entonces ejecuta postman/collection-auth.json
en su lugar.
Mostramos el proceso en este video de como correr pruebas de Postman.
Ambas colecciones se pueden ejecutar contra la base de datos de producción
real, pero puedes considerar crear una base de datos de prueba ya que las
pruebas para los endpoints de /user
realizan operaciones CRUD y crean y
eliminan un usuario cuyo correo es newUser@test.com
.
Para el login y los endpoints autenticados, tu base de datos necesita
tener un usuario cuyas credenciales coincidan con las variables
testUserEmail
y testUserPassword
de las pruebas del API que se
encuentran en ./postman/environment.json
, cuyos valores son
admin@test.com
y test
respectivamente. Recuerda que las contraseñas
están encriptadas, por lo que tu usuario no tendrá test
como una
contraseña sin cifrar en tu base de datos.
Además de estas pruebas y cualquier prueba unitaria,
puedes considerar escribir pruebas adicionales para probar los datos
devueltos por tu API. Agregar una colección de pruebas adicional
es una opción, o usar una biblioteca como supertest
para Node
u otra biblioteca con tu lenguaje de preferencia.
Te proponemos los siguientes pasos para iniciar con el proyecto
En primer lugar, asegúrate de comprender qué es una API REST. Para esto puedes consultar en internet o preguntarle a ChatGPT. Habla con una coach en tu proximo Office Hours para confirmar tus aprendizajes. En particular, te recomendamos ver leer este artículo.
La base de datos recomendada para tu aplicación es PostgreSQL. Te recomendamos usar vercel PostgreSQL para que no tengas que instalar PostgreSQL en tu computadora.
Para crear una base de datos PostgreSQL en Vercel usa la documentación oficial. Identifica la siguiente información porque la necesitarás para conectarte a tu base de datos
Una vez hayas creado una instancia de PostgreSQL en Vercel, deberás conectarte a ella. Te recomendamos que instales pgAdmin, un GUI (Graphical User Interface) para interactuar con la base de datos.
Con pgAdmin intenta conectarte a la base de datos usando la información suministrada por vercel.
En este punto, ya puedes trabajar en la Historia de Usuaria 1. Deberás crear las tablas en tu base de datos y cargar la información solicitada. Puedes crear una tabla usando la interfaz gráfica de pgAdmin o en usando SQL.
Ya es hora de escribir código. Tu primer objetivo es crear un proyecto que al ejecutarse cree un servidor HTTP que responda a la petición GET /taxis con un "hola mundo".
Te recomendamos usar Postman para confirmar que el endpoint que desarrolles responda segun lo solicitado.
El procedimiento recomendado dependerá del lenguaje de programación que hayas elegido:
Luego vas a necesitar elegir un módulo o librería para interactuar con nuestra base de datos desde el lenguaje de desarrollo elegido.
La librería recomendada dependerá del lenguaje de programación que hayas elegido:
Utiliza la librería elegida para consultar la base de datos y que tu API responda a la petición GET /taxis con el listado de taxis tal como se especifica en la documentación de API.
De nuevo, usa Postman para confirmar que el endpoint que desarrolles responda según lo solicitado.
De acuerdo a la documantación
documantación
el endpoint GET /taxis soporta 3 parametros: plate
, page
y limit
.
Modifica tu código para soportar peticiones a tu endpoint con estos parámetros. Usa Postman para probar tu endpoint con diferentes valores de estos parámetros.
Elige un módulo o librería para escribir pruebas e2e de tu endpoint.
La librería recomendada dependerá del lenguaje de programación que hayas elegido:
¡Felicitaciones! Hasta este punto ya has completado la Historia de Usuaria 2. Puedes continuar implementado las demás historias.
Si completaste todas las funcionalidades del proyecto te invitamos a trabajar en las funcionalides opcionales