FastAPI a Database Relazionale
Il generatore connection collega un progetto FastAPI a un progetto Python Relational Database, iniettando una sessione SQLModel tipizzata nei tuoi gestori di route tramite una dipendenza FastAPI.
Prerequisiti
Sezione intitolata “Prerequisiti”Prima di utilizzare questo generatore, assicurati di avere:
- Un progetto FastAPI (generato con
py#api --framework=fastapi), vedi la guidapy#api - Un progetto
py#rdb
Utilizzo
Sezione intitolata “Utilizzo”Esegui il Generatore
Sezione intitolata “Esegui il Generatore”Esegui questo generatore@aws/nx-plugin:connection
pnpm nx g @aws/nx-plugin:connection yarn nx g @aws/nx-plugin:connection npx nx g @aws/nx-plugin:connection bunx nx g @aws/nx-plugin:connection- Installa il Nx Console VSCode Plugin se non l'hai già fatto
- Apri la console Nx in VSCode
- Clicca su
Generate (UI)nella sezione "Common Nx Commands" - Cerca
@aws/nx-plugin - connection - Compila i parametri richiesti
- Clicca su
Generate
Componi il tuo comando5
Obbligatorio
Obbligatorio
Seleziona il tuo progetto FastAPI come sorgente e il tuo progetto di database relazionale come destinazione.
Opzioni
Sezione intitolata “Opzioni”sourceProjectObbligatoriostringIl progetto sorgente
targetProjectObbligatoriostringIl progetto di destinazione a cui connettersi
sourceComponentstringIl componente sorgente da cui connettersi (nome del componente, percorso relativo alla radice del progetto sorgente, o id del generatore). Usa '.' per selezionare esplicitamente il progetto come sorgente.
targetComponentstringIl componente destinazione a cui connettersi (nome del componente, percorso relativo alla radice del progetto destinazione, o id del generatore). Usa '.' per selezionare esplicitamente il progetto come destinazione.
preferInstallDependenciesbooleanPredefinito:trueSe preferire l'installazione delle dipendenze dopo l'esecuzione del generatore. Impostare su false per rimandare l'installazione quando si eseguono più generatori in batch (l'installazione viene comunque eseguita se necessaria affinché i generatori successivi possano calcolare il grafo dei progetti Nx); installare una volta alla fine.
Output del Generatore
Sezione intitolata “Output del Generatore”Il generatore modifica il tuo progetto FastAPI:
Directorypackages/my_api
- project.json Aggiunge una dipendenza da
devsul targetdevdel database - pyproject.toml Aggiunge il pacchetto del database come dipendenza del workspace
Directorymy_api
Directorydependencies
- my_db.py Dipendenza FastAPI
MyDbSessionper la sessione del database
- my_db.py Dipendenza FastAPI
- project.json Aggiunge una dipendenza da
Utilizzo del Database nei Gestori di Route
Sezione intitolata “Utilizzo del Database nei Gestori di Route”Questo generatore configura una FastAPI Dependency iniettabile che puoi utilizzare nei tuoi gestori di route:
from sqlmodel import selectfrom my_api.dependencies.my_db import MyDbSessionfrom my_scope_my_db.models.example import ExampleModel
@app.get("/examples")async def list_examples(my_db: MyDbSession): return (await my_db.execute(select(ExampleModel))).scalars().all()
@app.post("/examples")async def create_example(name: str, my_db: MyDbSession): item = ExampleModel(name=name) my_db.add(item) await my_db.commit() await my_db.refresh(item) return itemFastAPI apre automaticamente una nuova sessione per ogni richiesta e la chiude quando il gestore ritorna.
Infrastruttura
Sezione intitolata “Infrastruttura”Per consentire alla funzione Lambda FastAPI di connettersi al database a runtime, deve essere distribuita nello stesso VPC del database e deve avere accesso di rete e IAM.
Nel tuo stack dell’applicazione, distribuisci l’API nello stesso VPC del database, quindi chiama allowDefaultPortFrom e grantConnect per aprire il percorso di rete e concedere il permesso IAM rds-db:connect al gestore Lambda:
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { vpc, ... });
const api = new MyApi(this, 'Api', { integrations: MyApi.defaultIntegrations(this) .withDefaultOptions({ vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS }, }) .build(),});
Object.entries(api.integrations).forEach(([operation, integration]) => { db.allowDefaultPortFrom(integration.handler, `Allow ${operation} to connect to the database`); db.grantConnect(integration.handler);});Distribuisci le funzioni Lambda dell’API in una subnet privata con egress, non in una subnet privata isolata. A runtime, session_context() recupera la configurazione del database da AWS AppConfig, che è un endpoint di servizio AWS pubblico che richiede accesso internet in uscita.
Distribuisci l’API nello stesso VPC del database, concedigli rds-db:connect tramite additional_iam_policy_statements e apri il percorso di rete con una coppia di regole di security group:
L’esempio seguente fa riferimento alle risorse VPC dalla guida di distribuzione Python Relational Database: le subnet aws_subnet.database non hanno route internet, mentre le subnet aws_subnet.private hanno egress NAT.
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" vpc_id = aws_vpc.main.id database_subnet_ids = aws_subnet.database[*].id lambda_subnet_ids = aws_subnet.private[*].id}
module "api" { source = "../../common/terraform/src/app/apis/my-api" enable_vpc = true vpc_id = aws_vpc.main.id subnet_ids = aws_subnet.private[*].id
appconfig_application_id = module.runtime_config_appconfig.application_id appconfig_application_arn = module.runtime_config_appconfig.application_arn
additional_iam_policy_statements = [ { Effect = "Allow" Action = ["rds-db:connect"] Resource = [ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}" ] } ]}
resource "aws_vpc_security_group_ingress_rule" "api_to_database" { description = "Allow the API Lambda functions to connect to the database" security_group_id = module.my_database.security_group_id referenced_security_group_id = module.api.security_group_id from_port = module.my_database.cluster_port to_port = module.my_database.cluster_port ip_protocol = "tcp"}
resource "aws_vpc_security_group_egress_rule" "api_to_database" { description = "Allow outbound traffic from the API Lambda functions to the database" security_group_id = module.api.security_group_id referenced_security_group_id = module.my_database.security_group_id from_port = module.my_database.cluster_port to_port = module.my_database.cluster_port ip_protocol = "tcp"}Distribuisci le funzioni Lambda dell’API in subnet private con egress, non in subnet private isolate. appconfig_application_id/appconfig_application_arn provengono dall’applicazione AppConfig di configurazione runtime condivisa dichiarata una volta nel tuo modulo root, non dal modulo del database — passarli imposta RUNTIME_CONFIG_APP_ID sulle funzioni Lambda e concede loro l’accesso in lettura all’applicazione.
L’applicazione AppConfig espone il namespace database per impostazione predefinita, quindi la voce di configurazione runtime del modulo del database viene distribuita senza ulteriore configurazione.
Requisiti SSL per la Connessione Senza RDS Proxy
Sezione intitolata “Requisiti SSL per la Connessione Senza RDS Proxy”L’archivio di certificati CA integrato nell’ambiente di esecuzione Lambda Amazon Linux 2023 include le CA radice Amazon utilizzate da RDS, quindi non è necessaria alcuna configurazione aggiuntiva.
Quando si utilizza RDS Proxy, non è necessario configurare il bundle CA di RDS nella funzione Lambda.
Sviluppo Locale
Sezione intitolata “Sviluppo Locale”pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>Questo avvia la FastAPI e tutti i database connessi. La variabile d’ambiente LOCAL_DEV=true fa sì che il client del database si connetta al suo database Docker locale invece che ad Aurora.