Routes in Flask

Video thumbnail

Since we know how to define Hello World in the Flask project, the next thing we need to know is how to create routes. In Flask, we don't need to set up a separate configuration file, as is the case with Laravel's web.php; it's simply a decorator. In this article, I will show you how routes work in Flask, how to create dynamic routes, use different HTTP methods, and organize your application professionally.

What is a route in Flask and how does it work?

In Flask, a route is the link between a URL and a function that executes when a user visits that address. In other words: every time someone accesses `/products`, Flask looks for which function should execute to respond.

The heart of everything is in the decorator @app.route(), which tells the framework which URL to associate with each function:

from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
   return "Bienvenido a mi aplicación Flask"

Every time Flask receives a request, it goes through a simple flow:

  • It detects the requested route.
  • It searches for the associated function.
  • It generates a response and sends it to the browser.

Dynamic routes and variables in the URL

Many times we need a route to accept variables. For example, to show a user's profile based on their ID:

@app.route('/usuario/<int:id>')
def usuario(id):
   return f"Perfil del usuario {id}"

And yes, everything in Flask is small because it's a microframework, but completely functional.

Flask uses what are called converters, which define the expected data type:

  • string: default value.
  • int: whole numbers.
  • float: decimals.
  • path: text with /.
  • uuid: universal identifier.

You can also have optional variables or multiple parameters in the same URL:

@app.route('/producto/<categoria>/<int:id>')
def producto(categoria, id):
   return f"{categoria.capitalize()} - ID {id}"

HTTP Methods and Route Handlers

There are different HTTP methods we can use to make requests to the server; these methods are nothing more than a set of verbs used to perform different types of actions; the most common methods are GET, POST, PUT, PATCH, and DELETE:

  • GET: used to retrieve information from a web server. The information is sent in the request URL.
  • POST: used to send information to a web server. The information is sent in the request body.
  • PUT: used to update information on a web server. The information is sent in the request body.
  • PATCH: used to partially update information on a web server. The information is sent in the request body.
  • DELETE: used to delete information from a web server. The information is sent in the request URL.

All these methods have their equivalent in Flask; so far we have used GET methods to get data, but it is also possible to use others:

@app.route(<URI>, methods=('GET'))
@app.route(<URI>, methods=('POST'))
@app.route(<URI>, methods=('PUT'))
@app.route(<URI>, methods=('PATCH'))
@app.route(<URI>, methods=('DELETE'))

You can indicate several that more than one method is resolved by the same handler:

@app.route(<URI>, methods=('GET', 'POST'))

As you can see, we have a decorator function for each type of method, and it has a direct relationship with the type of HTTP request.

In Flask, you can define which methods each route accepts:

@app.route('/formulario', methods=('GET', 'POST'))
def formulario():
   if request.method == 'POST':
       nombre = request.form['nombre']
       return f"HI {name}!"
   return render_template('form.html')

GET and POST methods are usually used when the same route displays a form and processes the submitted data. This avoids duplicating views and keeps the code cleaner.

For REST APIs, you can also use PUT, PATCH, and DELETE in your handlers.

URL Building and the url_for() function

Instead of writing URLs by hand, Flask offers the url_for() function to build them dynamically:

from flask import url_for
@app.route('/dashboard')
def dashboard():
   return "Panel de control"
# En otra parte
url_for('dashboard')  # Devuelve '/dashboard'

Advantages:

  • If you change the route name, url_for updates automatically.
  • Improves project maintainability.
  • Avoids duplicate route errors.

You can also use it for static files:

<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">

Blueprints and Advanced Route Organization

As your application grows, grouping all routes in a single file becomes unmanageable.
This is where Blueprints come in, allowing you to modularize your app:

# usuarios.py from flask import Blueprint usuarios_bp = Blueprint('usuarios', __name__) @usuarios_bp.route('/profile') def perfil(): return "User Profile" # app.py from usuarios import usuarios_bp app.register_blueprint(usuarios_bp, url_prefix='/usuarios')

This way, you can have routes separated by areas: users, admin, products, etc.
This not only improves organization but also scalability.

Complete Example: Mini CRUD in Flask with REST Routes

To see everything in action, let's build a small example with CRUD:

# usuarios.py
from flask import Blueprint
usuarios_bp = Blueprint('usuarios', __name__)
@usuarios_bp.route('/perfil')
def perfil():
   return "Perfil de usuario
# app.py
from usuarios import usuarios_bp
app.register_blueprint(usuarios_bp, url_prefix='/user')

Security and Performance Best Practices

  • Escape variables in templates ({% raw %}{% raw %}{{ variable | safe }}{% endraw %}}).
  • Always validate user input, especially if it comes from forms or external JSON.
  • Use secure sessions (session with secret keys).
  • In production, combine Flask with Gunicorn + Nginx for better performance.

Frequently Asked Questions about Flask Routes (FAQ)

Why doesn't my route work or returns 404?
There is probably a syntax error or a conflict with another route. Use flask routes to list them all.

How to use GET and POST in the same route?
Define methods=('GET','POST') and check if request.method == 'POST'.

What is the difference between @app.route and Blueprints?
@app.route is used directly in the main app; Blueprints group routes into reusable modules.

Why does Flask redirect with a trailing slash?
Because it interprets /route/ as a "directory" and /route as an "action." Flask redirects automatically for consistency.

How to test my routes without running the server?
With test_request_context or Flask's built-in test client and pytest.

✅ Conclusion

Routes in Flask are the heart of any application: simple to define, but powerful when used correctly.
With a little practice—and paying attention to details like HTTP methods, Blueprints, and testing—you can build anything from small forms to robust APIs.

Understanding how Flask manages methods and routing allowed me to develop clean, organized, and easy-to-maintain apps.

The next step you should know is how to create environment variables using .env.

I agree to receive announcements of interest about this Blog.

There are different HTTP methods that we can use to make requests to the server; These methods are nothing more than a set of verbs that are used to perform different types of actions; The most common methods are GET, POST, PUT, PATCH and DELETE.

| 👤 Andrés Cruz

🇪🇸 En español