You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask中转发请求至其他API?如何基于数据库图创建动态处理器?

Flask请求转发与动态路由处理器实现方案

Great questions! Let's break this down step by step to solve both your requirements.

1. 基础:从Flask向其他API转发请求

The simplest way to forward requests in Flask is using the requests library to relay incoming requests to your target API, then pass the response back to the original client. Here's a practical example:

from flask import Flask, request, Response
import requests

app = Flask(__name__)

@app.route('/forward-to-api', methods=['GET', 'POST', 'PUT', 'DELETE'])
def forward_basic():
    # Replace this with your target API endpoint
    target_api_url = "https://your-target-service.com/desired-endpoint"
    
    # Copy incoming headers, excluding the Host header to avoid conflicts
    request_headers = dict(request.headers)
    request_headers.pop('Host', None)
    
    # Relay the request based on HTTP method
    try:
        if request.method == 'GET':
            api_response = requests.get(
                target_api_url,
                params=request.args,
                headers=request_headers
            )
        elif request.method == 'POST':
            # Handle both JSON and form data
            api_response = requests.post(
                target_api_url,
                json=request.get_json(silent=True),
                data=request.form,
                headers=request_headers
            )
        elif request.method == 'PUT':
            api_response = requests.put(
                target_api_url,
                json=request.get_json(),
                headers=request_headers
            )
        elif request.method == 'DELETE':
            api_response = requests.delete(
                target_api_url,
                headers=request_headers
            )
        else:
            return "Unsupported HTTP method", 405
        
        # Pass the target API's response back to the client
        return Response(
            content=api_response.content,
            status=api_response.status_code,
            headers=dict(api_response.headers)
        )
    except requests.exceptions.RequestException as e:
        return f"Failed to reach target API: {str(e)}", 503

if __name__ == '__main__':
    app.run(debug=True)

Key notes here:

  • We preserve query parameters, request body, and most headers
  • Added error handling for cases where the target API is unreachable
  • Supports all common HTTP methods

2. 动态请求处理器:基于数据库映射转发所有请求

To build a dynamic router that uses database-stored mappings, we'll need three core components: a database model for route mappings, a catch-all Flask route, and logic to match incoming paths to their target APIs.

Step 1: Define the Database Model

First, set up a model to store path-to-target mappings (using SQLAlchemy as an example):

from flask_sqlalchemy import SQLAlchemy

# Initialize SQLAlchemy with your Flask app
db = SQLAlchemy(app)

class RouteMapping(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    path_pattern = db.Column(db.String(255), unique=True, nullable=False)
    # Example patterns: '/api/users/<user_id>', '/payment/*'
    target_url = db.Column(db.String(255), nullable=False)
    # Example targets: 'https://user-service/api/users/<user_id>', 'https://payment-gateway.com/'

Run db.create_all() to generate the table in your database.

Step 2: Build the Catch-All Dynamic Router

Create a catch-all route that matches every incoming request, looks up the target in the database, and forwards the request:

from werkzeug.routing import Rule, Map

@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def dynamic_forward(path):
    # Look up the route mapping (you can optimize this with caching)
    # For pattern matching, we'll use Werkzeug's routing system to handle placeholders
    mappings = RouteMapping.query.all()
    
    target_url = None
    path_params = {}
    
    # Match incoming path to stored patterns
    for mapping in mappings:
        rule = Rule(mapping.path_pattern, endpoint='target')
        url_map = Map([rule])
        adapter = url_map.bind('localhost')
        try:
            _, path_params = adapter.match(f'/{path}')
            target_url = mapping.target_url.format(**path_params)
            break
        except:
            continue
    
    if not target_url:
        return "No target API configured for this path", 404
    
    # Forward the request (same logic as the basic example)
    request_headers = dict(request.headers)
    request_headers.pop('Host', None)
    
    try:
        if request.method == 'GET':
            api_response = requests.get(target_url, params=request.args, headers=request_headers)
        elif request.method == 'POST':
            api_response = requests.post(target_url, json=request.get_json(silent=True), data=request.form, headers=request_headers)
        elif request.method == 'PUT':
            api_response = requests.put(target_url, json=request.get_json(), headers=request_headers)
        elif request.method == 'DELETE':
            api_response = requests.delete(target_url, headers=request_headers)
        
        return Response(
            content=api_response.content,
            status=api_response.status_code,
            headers=dict(api_response.headers)
        )
    except requests.exceptions.RequestException as e:
        return f"Target API unavailable: {str(e)}", 503

Optimization Tips

  • Cache Mappings: Load all route mappings into memory on app startup (or use a cache like Redis) to avoid repeated database queries on every request.
  • Regex Patterns: For more complex matching, extend the model to support regex path patterns instead of simple placeholders.
  • Rate Limiting: Add rate limiting per target API to prevent overwhelming downstream services.
  • Logging: Log all forwarded requests for debugging and monitoring purposes.

内容的提问来源于stack exchange,提问作者angga prabuwisesa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:57:09