Amazon API Gateway è un servizio serverless che permette di creare, pubblicare e proteggere le API su qualsiasi tipo di tecnologia e qualsiasi dimensione di traffico, la sicurezza e il monitoraggio viene delegato al servizio di tpo serverless che permette di fare tutto in maniera agile e semplice. Le API fungono da “porta d’ingresso” (detto proprio EndPoint) per consentire alle applicazioni di accedere a dati e ai servizi di backend. La applicazione più usata è l’esposizione di servizi API RESTful oppure API WebSocket che abilitano applicazioni di comunicazione bidirezionale in tempo reale.
Inoltre il servizio è studiato per collegarsi e lavorare con tutti gli altri servizi AWS come Lambda, SQS, SNS e supporta nativamente la gestione di CORS e WAF in modo da rendere sicure le API con controlli di autenticazione e autorizzazione native. Il servizio API Gateway non prevede tariffe minime o costi di avvio ma il costo è calcolato in base al numero di chiamate API e per la quantità di dati trasferiti e, con il modello di prezzi a scaglioni di API Gateway.
La documentazione ufficiale descrive il funzionamento del servizio con uno schema, anche se può sembrare complicato in realtà si può vedere come il Gatewey si interfaccia con i vari servizi AWS come Lambda, può esporre servizi esterni “on-premises” e gestisce una cache interna.
Per ogni API configurata con questo servizio, è possibile impostare le seguenti configurazioni:
- Resources: per ogni risorsa è necessario impotare il tipo di metodo HTTP (GET, POST, PUT, ec…) e la destinazione (come una funzione Lambda). La console web permette anche di eseguire un test della risorsa e permette di configurare il CORS.
- Stages: per ogni risorsa è possibile esporre i servizi REST in stage separati che saranno raggiungibili con l’EndPoint:
https://{restapi-id}.execute-api.{region}.amazonaws.com/{stageName}
- Authorizers: per ogni risorsa è possibile creare uno “strato di sicurezza”, per esempio è possibile creare e configurare una lambda function che effettui una verifica di autorizzazione/autenticazione prima della chiamata alla destinazione della risorsa.
- Gateway responses e Resource policy: per ogni risorsa è possibile aggiungere delle configurazioni particolari, per esempio per un errore 500 è possibile aggiungere header alla risposta
- Documentation: per ogni risorsa esposta dal servizio è possibile configurare la documentazione secondo gli standard RESTfull come Swagger o altre librerie standard
- Dashboard: per ogni risorsa è possibile accedere ad una dashboard di monitoraggio del traffico, degli errori e dello stato degli stage
- API settings: per ogni risorsa è possibile visualizzare le impostazioni base come l’EndPoint e i Timeout (TTL).
Per maggior in formazioni si rimanda alla documentazione ufficiale anche se è sempre conveniente usare CloudFormation o altri sistemi per creare API e risorse.
La CLI mette a disposizione tutta una serie di metodi per la gestione delle API, per la creazione di una risorsa esposta con l’API Gateway per chiamare una funzione lambda si può seguire la procedura descritta nella documentazione ufficiale. I cui principali passi sono:
- Creazione delle regola IAM che permetterà alla API di eseguire la funzione Lambda (ricordandosi che per default su AWS tutto è negato a meno che non sia strettamente indicato con una regola IAM)
echo "{\"Version\": \"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}" > role.json aws iam create-role --role-name lambda-api-role --assume-role-policy-document file://role.json aws iam attach-role-policy --role-name lambda-api-role --policy-arn "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" aws iam attach-role-policy --role-name lambda-api-role --policy-arn "arn:aws:iam::aws:policy/service-role/AWSLambdaRole"
- Creazione della risorsa
aws apigateway create-rest-api --name 'ApiGatewayEsCLI' { "id": "r43b0zk1lg", ... } aws apigateway get-resources --rest-api-id r43b0zk1lg { "items": [{"id": "yd6srqipx0", aws apigateway create-resource --rest-api-id r43b0zk1lg --parent-id yd6srqipx0 --path-part list { "id": "w1iqv9", aws apigateway put-method --rest-api-id r43b0zk1lg --resource-id w1iqv9 --http-method GET --authorization-type "NONE" {"httpMethod": "GET","authorizationType": "NONE","apiKeyRequired": false} aws apigateway put-method-response --rest-api-id r43b0zk1lg --resource-id w1iqv9 --http-method GET --status-code 200 { "statusCode": "200" }
- Destinazione della risorsa: la funzione lambda con l’indicazione della lambda nel parametro uri (con
/invocation
finale altrimenti non funziona) e la regola iam nel parametro credentials:
aws apigateway put-integration --rest-api-id r43b0zk1lg --resource-id w1iqv9 --type AWS_PROXY --http-method GET --integration-http-method POST --uri arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:xxxx:function:yyyyyy/invocations --credentials arn:aws:iam::740456629644:role/lambda-api-role
- Deploy della risorsa in uno stage
aws apigateway create-deployment --rest-api-id r43b0zk1lg --stage-name dev --stage-description 'DEV stage' --description 'First deployment'
- Test di invocazione
curl https://xxxx.execute-api.eu-west-1.amazonaws.com/dev/list
Per quanto riguarda la gestione delle API la CLI mette a disposizione i comandi:
- recuperare l’elenco delle API
aws apigateway get-rest-apis --output table --query 'items[*].[name,id,createdDate]'
- recuperare l’elenco delle risorse di una API
aws apigateway get-resources --rest-api-id r43b0zk1lg --query 'items[*].[id,path,resourceMethods]'
- recuperare il dettaglio di un metodo
aws apigateway get-method --rest-api-id r43b0zk1lg --resource-id w1iqv9 --http-method GET
- recuperare l’elenco degli stage di una API
aws apigateway get-deployments --rest-api-id r43b0zk1lg --output table --query 'items[*].[description,id,createdDate]'
- recuperare l’elenco degli stage
aws apigateway get-stages --rest-api-id r43b0zk1lg --output table --query 'items[*].[deploymentId,stageName,description]'
- eliminare una api
aws apigateway delete-rest-api --rest-api-id r43b0zk1lg
Per quanto riguarda la libreria SDK, sono stati studiati metodi specifici per la gestione delle API esposte con questo servizio. I principali metodi per recuperare le informazioni di API, risorse, metodi e stages sono:
def api_list(profile_name): boto3.setup_default_session(profile_name=profile_name) client = boto3.client('apigateway') response = client.get_rest_apis( limit=100 ) if 'items' in response: return response['items'] return [] def resouce_list(profile_name,api_ip): boto3.setup_default_session(profile_name=profile_name) client = boto3.client('apigateway') response = client.get_resources( restApiId=api_ip, limit=100) if 'items' in response: return response['items'] return [] def method_detail(profile_name,api_ip,resouce_id,method): boto3.setup_default_session(profile_name=profile_name) client = boto3.client('apigateway') response = client.get_method(restApiId=api_ip,resourceId=resouce_id,httpMethod=method) return response def stage_list(profile_name,api_ip): boto3.setup_default_session(profile_name=profile_name) client = boto3.client('apigateway') response = client.get_stages( restApiId=api_ip) if 'item' in response: return response['item'] return response
Con il servizio CloudFormation è possibile creare infrastrutture programmandone i componenti, nella versione più strong e pura il servizio permette di creare i componenti previsti dal API Gateway di tipo:
AWS::ApiGateway::RestApi AWS::ApiGateway::Resource AWS::ApiGateway::Method AWS::ApiGateway::Model AWS::ApiGateway::Stage AWS::ApiGateway::Deployment
La documentazione ufficiale è ricca di esempi completi per l’utilizzo di questo tipo. Un esempio completo è disponibile al solito repository:
https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio10apiGateway
Tuttavia il servizio CloudFormation mette a disposizione una via molto più veloce e semplice per costruire API di tipo RESTful, usando un unico componente di tipo:
AWS::Serverless::Api
questa tecnica è descritta in un articolo dedicato nella sezione dei template evoluti di CloudFromation.