De un error 404 a una API avanzada: Optimización, búsqueda y escalabilidad - Episodio 3

Ayer me topé con un problema que parecía menor, pero terminó llevándome a mejorar por completo la API de mi SaaS.

Además de coonseguir subirme a una montaña rusa de emociones, cavalgando entre alegría y desesperación.

Intentaba listar los datos con un GET /parts y… ¡error 404!

Índice
  1. 📅 Diario de un SaaS: De un error crítico a una API potente y optimizada
  2. 🔍 Primer problema: Un 404 Not Found que me hizo repensar todo
    1. No podia ejecutar Flask Routes
    2. Activando entorno virtual
    3. Después de tanto mareo de vuelta a Flask Routes
  3. 🚀 Primera mejora: GET /parts con filtros avanzados
  4. 🔎 Segunda mejora: Búsqueda optimizada con Full-Text Search
  5. 🔄 Tercera mejora: Edición y eliminación de registros
  6. ⚡ Cuarta mejora: Pruebas de rendimiento con Locust
  7. 📈 Lecciones aprendidas y próximos pasos
  8. 📌 Reflexión final: Optimizar desde el inicio evita problemas a futuro.

📅 Diario de un SaaS: De un error crítico a una API potente y optimizada

Esto me hizo replantear no solo cómo recuperar datos, sino cómo optimizar la API para hacerla más rápida, escalable y flexible. Lo que empezó como un simple bug, terminó en una serie de mejoras clave:

Filtros avanzados para encontrar información específica sin ralentizar la API.
Búsqueda optimizada con Full-Text Search, sinónimos y términos relacionados.
Edición y eliminación de registros con PUT y DELETE.
Pruebas de carga para garantizar que la API pueda escalar sin perder velocidad.

Si estás desarrollando una API para tu SaaS o en un fregado similar...

Quédate, porque voy a contarte todos los problemas que encontré y cómo los resolví.


🔍 Primer problema: Un 404 Not Found que me hizo repensar todo

Mi primera reacción fue revisar si la ruta GET /parts estaba bien configurada.

Ejecuté en el powershell de windows

bash
flask routes
Powershell_error_flask
Error al ejecutar Flask en Powershell

Primera piedra en el camino

No podia ejecutar Flask Routes

Después de un rato de tirar del hilo tuve descubrí que era un problema que powershell no me estaba dejando ejecutar scripts.

Por seguridad, sí.

Por mi seguridad, sí.

Por la seguridad de todos, sí.

Pero mira que me dió dolores de cabeza.

Ejecutando el siguiente comando en PowerShell (como Administrador):

Set-ExecutionPolicy Unrestricted -Scope Process
Conseguí desbloquearlo... pero eso no era todo.

Activando entorno virtual

Otro de los palos en la rueda era que necesitaba ejecutar previamente el entorno virtual.

Para eso

Después de ejecutar el comando anterior, prueba nuevamente:

Para eso en powershell tuve que ejecutar VENV.
.\venv\Scripts\activate

Después de tanto mareo de vuelta a Flask Routes

Y por fin ejecuté

bash
flask routes

Y ahí estaba el problema: la ruta no existía en la API.

Pero en lugar de simplemente agregarla, decidí hacerlo bien y aprovechar para mejorar todo el sistema de recuperación de datos.

Los objetivos eran claros:

🔹 Agregar filtros avanzados para que los usuarios encuentren lo que buscan más rápido.
🔹 Optimizar la búsqueda para que reconozca términos similares.
🔹 Facilitar la edición y eliminación de registros sin procesos engorrosos.
🔹 Garantizar que la API funcione bien bajo carga alta sin ralentizarse.

solucionando-problema-API


🚀 Primera mejora: GET /parts con filtros avanzados

Para hacer más eficiente la búsqueda de datos, agregamos filtros inteligentes en la API.

📌 Ejemplo de consulta avanzada:

bash
GET /parts?brand=Seiko&status=Nuevo&min_price=100&max_price=500

Así evitamos sobrecargar la base de datos con consultas innecesarias.

📌 Código en Flask:

@app.route('/parts', methods=['GET'])
@jwt_required()
def get_parts():
query = Part.query
if 'brand' in request.args:
query = query.filter_by(brand=request.args['brand'])
if 'status' in request.args:
query = query.filter_by(status=request.args['status'])
if 'min_price' in request.args and 'max_price' in request.args:
query = query.filter(Part.price.between(request.args['min_price'], request.args['max_price']))
parts = query.all()
result = [{
"id": part.id,
"title": part.title,
"brand": part.brand,
"price": part.price,
"status": part.status
} for part in parts]
return jsonify(result), 200

✅ Ahora los usuarios pueden recuperar solo la información que realmente necesitan, reduciendo el tiempo de respuesta de la API.


🔎 Segunda mejora: Búsqueda optimizada con Full-Text Search

La siguiente optimización fue mejorar cómo se busca la información en la API.

Problema: Antes, la API solo devolvía coincidencias exactas.

Solución: Implementamos Full-Text Search en PostgreSQL para permitir búsquedas más inteligentes y rápidas.

📌 Código en Flask:

@app.route('/search', methods=['GET'])
@jwt_required()
def search():
query = request.args.get('q', '')
if not query:
return jsonify({'error': 'Debe proporcionar un término de búsqueda'}), 400
sql = text(\"""
SELECT id, title, brand, price
FROM parts
WHERE search_vector @@ to_tsquery('spanish', :query)
ORDER BY ts_rank_cd(search_vector, to_tsquery('spanish', :query)) DESC;
\""")

results = db.session.execute(sql, {'query': query}).fetchall()
return jsonify([dict(row) for row in results])

📌 Ejemplo de búsqueda avanzada:

sql
GET /search?q=procesador

🔹 Antes: Solo coincidencias exactas.
🔹 Ahora: También reconoce términos similares, mejorando la precisión de búsqueda.

✅ Esto mejora la experiencia de usuario y evita resultados vacíos por pequeñas variaciones en la escritura.


🔄 Tercera mejora: Edición y eliminación de registros

Ahora que la API puede buscar y filtrar datos correctamente, el siguiente paso fue permitir modificar y eliminar registros.

📌 Ejemplo de actualización de datos (PUT /parts/10)

json
{
"price": 299.99,
"status": "Seminuevo"
}

📌 Ejemplo de eliminación de un registro (DELETE /parts/10)
✅ Con esto, la API permite una gestión más eficiente sin tener que eliminar manualmente registros en la base de datos.


⚡ Cuarta mejora: Pruebas de rendimiento con Locust

El siguiente reto era asegurar que la API funcionara bien bajo carga alta.

Para ello, realizamos pruebas con Locust, simulando cientos de usuarios accediendo simultáneamente.

📌 Ejemplo de archivo locustfile.py para testear la API:

from locust import HttpUser, task, between

class APIUser(HttpUser):
host = "http://127.0.0.1:5000"
wait_time = between(1, 5)

@task
def get_parts(self):
self.client.get("/parts?page=1&per_page=20")

@task
def search_parts(self):
self.client.get("/search?q=Seiko")

✅ Gracias a estas pruebas, optimizamos las consultas y redujimos los tiempos de respuesta bajo alta demanda.


📈 Lecciones aprendidas y próximos pasos

Lo que comenzó con un error 404, nos llevó a hacer mejoras clave en nuestra API:

Ahora la API es más rápida y flexible con GET /parts optimizado.
Los usuarios pueden buscar información con términos relacionados (GET /search).
Se pueden modificar y eliminar datos fácilmente (PUT y DELETE).
Las pruebas de carga aseguraron que la API escale sin problemas.

📌 Próximo paso: Optimizar aún más el tiempo de respuesta e integrar nuevas funcionalidades basadas en las necesidades de los usuarios. 🚀


📌 Reflexión final: Optimizar desde el inicio evita problemas a futuro.


Lo que parecía un simple bug, me llevó a crear una API más sólida y preparada para escalar.

💡 Si estás desarrollando una API, no te conformes con hacer que funcione. Piensa en cómo optimizarla desde el principio.

📢 ¿Has tenido problemas con el rendimiento de tu API?

Cuéntamelo en los comentarios así dejaremos de sufrir en silencio.

Si quieres conocer otros artículos parecidos a De un error 404 a una API avanzada: Optimización, búsqueda y escalabilidad - Episodio 3 puedes visitar la categoría Proyecto-IA.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir