Expressify Examples

Learn how to use Expressify with practical, real-world examples that demonstrate the power and flexibility of the framework.

Coding Styles: Choose Your Preference

Expressify offers flexibility in how you define your routes and applications. Choose the style that best fits your project and preferences.

Decorator Syntax
Non-Decorator Syntax

Decorator syntax offers a clean, concise way to define routes directly above handler functions.

from expressify import expressify

app = expressify()

@app.get('/')
def home(req, res):
    res.send('Hello World!')

@app.get('/users/:id')
def get_user(req, res):
    user_id = req.params.get('id')
    res.send(f'User: {user_id}')

@app.post('/users')
def create_user(req, res):
    data = req.body
    res.status(201).json({'message': 'User created', 'data': data})

if __name__ == '__main__':
    app.listen(port=3000, hostname='127.0.0.1', callback=lambda: print('Server running on port 3000'))

Benefits of Both Approaches

Decorator Syntax

  • Clean and concise code organization
  • Routes and handlers visually paired
  • Similar to Flask and FastAPI style
  • Great for quickly defining routes

Non-Decorator Syntax

  • Easy dynamic route registration
  • Better for configuration-driven setup
  • More similar to Express.js style
  • Cleaner separation of definitions

Advanced Example: Dynamic Route Registration

The non-decorator syntax is particularly useful for dynamic route registration, such as loading routes from a configuration file:

routes_config.json

{
  "routes": [
    {
      "path": "/api/products",
      "method": "get",
      "handler": "get_products"
    },
    {
      "path": "/api/products/:id",
      "method": "get",
      "handler": "get_product_by_id"
    },
    {
      "path": "/api/products",
      "method": "post",
      "handler": "create_product"
    }
  ]
}

app.py

import json
from expressify import expressify

app = expressify()

# Handler functions
def get_products(req, res):
    res.json([{"id": 1, "name": "Product 1"}, {"id": 2, "name": "Product 2"}])

def get_product_by_id(req, res):
    product_id = req.params.get('id')
    res.json({"id": product_id, "name": f"Product {product_id}"})

def create_product(req, res):
    res.status(201).json({"message": "Product created"})

# Load routes from config file
with open('routes_config.json', 'r') as f:
    config = json.load(f)

# Register routes dynamically
for route in config['routes']:
    handler = globals()[route['handler']]
    method = route['method'].lower()
    
    # Use getattr to dynamically call the appropriate method
    getattr(app, method)(route['path'], handler)

if __name__ == '__main__':
    app.listen(port=3000, hostname='127.0.0.1', callback=lambda: print('Server running on port 3000'))

Middleware Usage

Middleware functions have access to the request and response objects and can perform actions before the final route handler.

Global Middleware
Route-Specific Middleware

Global middleware is applied to all routes in the application.

from expressify import Expressify
import time
import json

app = Expressify()

# Logger middleware
def logger_middleware(req, res, next):
    """Log request information and timing data"""
    start_time = time.time()
    
    print(f"Request: {req.method} {req.path}")
    
    # Call the next middleware/route handler
    result = next()
    
    # Calculate and log timing
    duration = (time.time() - start_time) * 1000  # Convert to ms
    print(f"Response: {res.status_code} - {duration:.2f}ms")
    
    return result

# JSON Parser middleware
def json_parser_middleware(req, res, next):
    """Parse JSON request bodies"""
    if 'application/json' in req.get_header('content-type', ''):
        try:
            if req.body:
                req.json = json.loads(req.body)
        except json.JSONDecodeError:
            return res.status(400).json({
                'error': 'Invalid JSON',
                'message': 'Failed to parse request body as JSON'
            })
    
    # Call the next middleware/route handler
    return next()

# Error Handler middleware
def error_handler_middleware(req, res, next):
    """Handle errors in the middleware chain"""
    try:
        # Call the next middleware/route handler
        return next()
    except Exception as e:
        print(f"Error: {str(e)}")
        return res.status(500).json({
            'error': 'Internal Server Error',
            'message': str(e)
        })

# Apply middleware to all routes
app.use(logger_middleware)
app.use(json_parser_middleware)
app.use(error_handler_middleware)

@app.get('/')
def home(req, res):
    res.send('Hello World!')

@app.post('/api/data')
def create_data(req, res):
    # The JSON parser middleware will have already parsed the JSON body
    if hasattr(req, 'json'):
        return res.status(201).json({
            'message': 'Data received successfully',
            'data': req.json
        })
    else:
        return res.status(400).json({
            'error': 'No data provided',
            'message': 'Request body should contain JSON data'
        })

if __name__ == '__main__':
    app.listen(port=3000)

Common Middleware Use Cases

Authentication

Verify user identity before allowing access to protected routes

Logging

Record request details and response times for monitoring

Error Handling

Catch and process errors to return appropriate responses

CORS

Add Cross-Origin Resource Sharing headers to enable cross-origin requests

Rate Limiting

Restrict request frequency to prevent abuse or API overload

Request Validation

Validate request data before it reaches the route handlers

Compression

Compress response data to reduce bandwidth and improve performance

Body Parsing

Parse request bodies (JSON, form data) and make data available to handlers

Security Headers

Add security-related HTTP headers to strengthen application security

Featured Examples

Basic Routing

Learn how to define routes with path parameters and handle different HTTP methods.

routes.py
from expressify import Expressify

app = Expressify()

# Simple route
@app.get('/')
def home(req, res):
    return res.send('Welcome to Expressify!')

# Route with parameters
@app.get('/users/:id')
def get_user(req, res):
    user_id = req.params['id']
    return res.json({
        'id': user_id, 
        'name': 'John Doe'
    })

# REST API routes
@app.get('/api/products')
def get_products(req, res):
    return res.json([
        {'id': 1, 'name': 'Laptop'},
        {'id': 2, 'name': 'Phone'}
    ])

@app.post('/api/products')
def create_product(req, res):
    new_product = req.body
    return res.status(201).json({
        'id': 3, 
        'name': new_product['name']
    })

app.listen(port=3000)
View example

Middleware

Implement authentication, logging, and request processing with middleware.

error_handling.py
from expressify import Expressify

app = Expressify()

# Error handling middleware
def error_middleware(req, res, next):
    try:
        return next()
    except Exception as e:
        if isinstance(e, ValueError):
            return res.status(400).json({
                'error': 'Bad Request',
                'message': str(e)
            })
        else:
            # Log the error
            print(f"Error: {str(e)}")
            return res.status(500).json({
                'error': 'Internal Server Error',
                'message': 'Something went wrong'
            })

# Apply globally
app.use(error_middleware)

@app.get('/api/users/:id')
def get_user(req, res):
    user_id = req.params['id']
    
    # Simulate database lookup
    if user_id == '999':
        raise ValueError('User not found')
    
    if not user_id.isdigit():
        raise ValueError('Invalid user ID')
        
    return res.json({'id': user_id, 'name': 'John Doe'})
View example

Static Files

Serve static files and render dynamic HTML content with ease.

static_files.py
from expressify import Expressify
import os

app = Expressify()

# Serve static files from the 'public' directory
app.serve_static('public')

# Dynamic route that renders HTML
@app.get('/dashboard')
def dashboard(req, res):
    username = req.query.get('user', 'Guest')
    return res.html(f"""
    
    
    
        Dashboard
        
    
    
        

Welcome, {username}!

This is your dashboard

""") # Ensure the public directory exists if not os.path.exists('public'): os.makedirs('public') app.listen(port=3000)
View example

More Examples

Community Examples

Explore examples created by the Expressify community or share your own projects built with Expressify.

API Authentication

Secure your API routes with a simple authentication middleware that protects sensitive endpoints.

from expressify import Expressify

app = Expressify()

# API Key authentication middleware
def auth_middleware(req, res, next):
    """Check for API key on protected routes"""
    if req.path.startswith('/protected'):
        api_key = req.get_header('x-api-key')
        
        if not api_key:
            return res.status(401).json({
                'error': 'Authentication required',
                'message': 'Missing API key'
            })
        
        if api_key != 'valid_key':
            return res.status(403).json({
                'error': 'Access denied',
                'message': 'Invalid API key'
            })
            
        # If authentication passes, add user info to request
        req.user = {'id': 123, 'role': 'user'}
    
    # Continue to next middleware or route handler
    return next()

# Apply the middleware globally
app.use(auth_middleware)

# Protected route requiring authentication
@app.get('/protected/data')
def protected_data(req, res):
    # req.user is available because of auth_middleware
    return res.json({
        'message': 'You have access to protected data',
        'user_id': req.user['id'],
        'role': req.user['role']
    })

# Public route (no authentication required)
@app.get('/public/data')
def public_data(req, res):
    return res.json({
        'message': 'This is public data',
        'timestamp': '2023-06-15T12:00:00Z'
    })

if __name__ == '__main__':
    app.listen(port=3000)
    print("Server running on port 3000")

Testing API Authentication

To test protected routes, include the API key in your request headers:

curl -H "X-API-Key: valid_key" http://localhost:3000/protected/data