Este blog explicou os seguintes conceitos para aplicativos sem servidor até o momento:
O terceiro blog da série sem servidor explicará como criar um microsserviço simples usando o Amazon API Gateway, o AWS Lambda e o Couchbase. Leia blogs anteriores para obter mais contexto sobre o AWS Lambda. Gateway de API da Amazon é um serviço totalmente gerenciado que facilita aos desenvolvedores a criação, publicação, manutenção, monitoramento e segurança de APIs em qualquer escala. O Amazon API Gateway lida com todas as tarefas envolvidas na aceitação e no processamento de até centenas de milhares de chamadas de API simultâneas, incluindo gerenciamento de tráfego, autorização e controle de acesso, monitoramento e gerenciamento de versões de API. Veja a seguir os principais componentes dessa arquitetura:
- O cliente pode ser curl, AWS CLI, cliente Postman ou qualquer outra ferramenta/API que possa invocar um ponto de extremidade REST.
- O API Gateway é usado para provisionar APIs. O recurso de nível superior está disponível no caminho
/livros
. HTTPOBTER
ePOST
são publicados para o recurso. - Cada API aciona uma função Lambda. Duas funções Lambda são criadas,
lista de livros
para listar todos os livros disponíveis ecriar livro
para criar um novo livro. - O Couchbase é usado como um armazenamento de persistência no EC2. Todos os documentos JSON são armazenados e recuperados desse banco de dados.
Vamos começar!
Criar função de IAM
As funções do IAM terão políticas e relações de confiança que permitirão que essa função seja usada no API Gateway e execute a função Lambda. Vamos criar uma nova função de IAM:
1 2 3 |
aws iam criar-função --função-nome microserviceRole --assumir-função-política-documento arquivo://./trust.json |
--assume-role-policy-document
define o documento de política de relacionamento de confiança que concede permissão a uma entidade para assumir a função. trust.json
está em github.com/arun-gupta/serverless/blob/master/aws/microservice/trust.json e se parece com isso:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "Versão": "2012-10-17", "Declaração": [ { "Sid": "", "Efeito": "Permitir", "Principal": { "Serviço": [ "lambda.amazonaws.com", "apigateway.amazonaws.com" ] }, "Ação": "sts:AssumeRole" } ] } |
Essa relação de confiança permite que as funções Lambda e o API Gateway assumam essa função durante a execução. Associe políticas a essa função como:
1 2 3 4 |
aws iam colocar-função-política --função-nome microserviceRole --política-nome microPolítica --política-documento arquivo://./policy.json |
policy.json
está em github.com/arun-gupta/serverless/blob/master/aws/microservice/policy.json e se parece com isso:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
{ "Versão": "2012-10-17", "Declaração": [ { "Efeito": "Permitir", "Ação": [ "logs:*" ], "Recurso": "arn:aws:logs:*:*:*" }, { "Efeito": "Permitir", "Ação": [ "apigateway:*" ], "Recurso": "arn:aws:apigateway:*::/*" }, { "Efeito": "Permitir", "Ação": [ "execute-api:Invoke" ], "Recurso": "arn:aws:execute-api:*:*:*:*" }, { "Efeito": "Permitir", "Ação": [ "lambda:*" ], "Recurso": "*" } ] } |
Essa política generosa permite quaisquer permissões sobre os registros gerados no CloudWatch para todos os recursos. Além disso, ela permite todas as permissões do Lambda e do API Gateway para todos os recursos. Em geral, somente a política necessária seria fornecida a recursos específicos.
Criar funções Lambda
As etapas detalhadas para criar funções Lambda são explicadas em FaaS sem servidor com AWS Lambda e Java. Vamos criar as duas funções Lambda conforme exigido em nosso caso:
1 2 3 4 5 6 7 8 9 10 11 12 |
aws lambda criar-função --função-nome MicroserviceGetAll --função arn:aws:iam::598307997273:função/microserviceRole --manipulador org.amostra.sem servidor.aws.couchbase.BaldeGetAll --zíper-arquivo arquivob:///Usuários/arungupta/workspaces/serverless/aws/microservice/microservice-http-endpoint/target/microservice-http-endpoint-1.0-SNAPSHOT.jar --descrição "Ponto de extremidade HTTP de microsserviço - Obter tudo" --tempo de execução java8 --região nós-oeste-1 --tempo limite 30 --memória-tamanho 1024 --ambiente Variáveis={COUCHBASE_HOST=ec2-52-53-193-176.us-oeste-1.compute.amazonaws.com} --publicar |
Alguns dos principais itens a serem observados nessa função são:
- Função de IAM
microserviceRole
criado na etapa anterior é explicitamente especificado aqui - O manipulador é
org.sample.serverless.aws.couchbase.BucketGetAll
classe. Essa classe consulta o banco de dados do Couchbase definido usando o parâmetroCOUCHBASE_HOST
variável de ambiente.
Crie a segunda função Lambda:
1 2 3 4 5 6 7 8 9 10 11 12 |
aws lambda criar-função --função-nome MicroservicePost --função arn:aws:iam::598307997273:função/microserviceRole --manipulador org.amostra.sem servidor.aws.couchbase.BucketPost --zíper-arquivo arquivob:///Usuários/arungupta/workspaces/serverless/aws/microservice/microservice-http-endpoint/target/microservice-http-endpoint-1.0-SNAPSHOT.jar --descrição "Ponto de extremidade HTTP de microsserviço - Post" --tempo de execução java8 --região nós-oeste-1 --tempo limite 30 --memória-tamanho 1024 --ambiente Variáveis={COUCHBASE_HOST=ec2-52-53-193-176.us-oeste-1.compute.amazonaws.com} --publicar |
O manipulador para essa função é org.sample.serverless.aws.couchbase.BucketPost
classe. Essa classe cria um novo documento JSON no banco de dados do Couchbase identificado por COUCHBASE_HOST
variável de ambiente. O código-fonte completo dessas classes está em github.com/arun-gupta/serverless/tree/master/aws/microservice/microservice-http-endpoint.
Recurso do gateway de API
Crie uma API usando o Amazon API Gateway e teste-a e Criar uma API para expor uma função Lambda fornecem etapas e explicações detalhadas sobre como usar o API Gateway e as funções Lambda para criar sistemas de back-end avançados. Este blog fará uma rápida descrição das etapas, caso você queira ir direto ao ponto. Vamos criar recursos do API Gateway.
- A primeira etapa é criar uma API:
123aws apigatewaycriar-descanso-API--nome Livro
Isso mostra a saída como:
12345{"name" (nome): "Livro","id": "lb2qgujjif","createdDate": 1482998945}
O valor deid
é o ID da API. No nosso caso, élb2qgujjif
. - Encontre o ROOT ID da API criada, pois ele é necessário para a próxima invocação da CLI do AWS:
1aws apigateway obter-recursos --descanso-API-id lb2qgujjif
Isso mostra o resultado:
12345678{"itens": [{"caminho": "/","id": "hgxogdkheg"}]}
Valor deid
é a ID ROOT. Essa também é a ID PARENT do recurso de nível superior. - Criar um recurso
1234aws apigateway criar-recurso--descanso-API-id lb2qgujjif--pai-id hgxogdkheg--caminho-parte livros
Isso mostra o resultado:
123456{"caminho": "/livros","pathPart": "livros","id": "vrpkod","parentId": "hgxogdkheg"}
Valor deid
é RESOURCE ID (ID do recurso).
A API ID e a RESOURCE ID são usadas para invocações subsequentes da AWS CLI.
Método POST do gateway de API
Agora que o recurso foi criado, vamos criar o HTTP POST
nesse recurso.
- Criar um
POST
método
12345aws apigateway colocar-método--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método POST--autorização-tipo NENHUM
para ver a resposta:
12345{"apiKeyRequired": falso,"httpMethod": "POST","authorizationType": "NONE"} - Defina a função Lambda como destino do método POST:
1234567aws apigateway colocar-integração--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método POST--tipo AWS--integração-http-método POST--uri arn:aws:apigateway:nós-oeste-1:lambda:caminho/2015-03-31/funções/arn:aws:lambda:nós-oeste-1::função:MicroservicePost/invocações
Certifique-se de substituircom o ID de sua conta do AWS. O ID da API e o ID do recurso da seção anterior também são usados aqui.
--uri
é usado para especificar o URI da entrada de integração. O formato do URI é fixo. Essa CLI mostrará o resultado como:
12345678{"httpMethod": "POST","passthroughBehavior" (comportamento de passagem): "WHEN_NO_MATCH","cacheKeyParameters": [],"tipo": "AWS","uri": "arn:aws:apigateway:us-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-1::function:MicroservicePost/invocations","cacheNamespace": "vrpkod"} - Conjunto
tipo de conteúdo
da resposta do método POST:
123456aws apigateway colocar-método-resposta--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método POST--status-código 200--resposta-modelos "{"aplicativo/json": "Vazio"}"
para ver a resposta:
123456{"responseModels": {"application/json": "Vazio"},"statusCode": "200"} - Conjunto
tipo de conteúdo
da resposta de integração do método POST:
123456aws apigateway colocar-integração-resposta--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método POST--status-código 200--resposta-modelos "{"aplicativo/json": "Vazio"}"
para ver a resposta:
123456{"statusCode": "200","responseTemplates": {"application/json": "Vazio"}} - Implantar a API
123aws apigateway criar-implantação--descanso-API-id lb2qgujjif--estágio-nome teste
para ver a resposta
1234{"id": "9wi991","createdDate": 1482999187} - Conceder permissão para que o API Gateway invoque a função Lambda:
123456aws lambda adicionar-permissão--função-nome MicroservicePost--declaração-id apigateway-teste-postagem-1--ação lambda:InvokeFunction--principal apigateway.amazonaws.com--fonte-arn "arn:aws:execute-api:us-west-1::lb2qgujjif/*/POST/books"
Além disso, conceda permissão à API implantada:
123456aws lambda adicionar-permissão--função-nome MicroservicePost--declaração-id apigateway-teste-postagem-2--ação lambda:InvokeFunction--principal apigateway.amazonaws.com--fonte-arn "arn:aws:execute-api:us-west-1::lb2qgujjif/test/GET/books" - Teste o método da API:
123456aws apigateway teste-invocar-método--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método POST--caminho-com-consulta-string ""--corpo "{"id": "1", "nome do livro": "teste livro", "isbn": "123", "custo": "1.23"}"
para ver a resposta:
12345678910{"status": 200,"corpo": "Vazio","log": "Registro de execução da solicitação test-requestnThu Dec 29 08:16:05 UTC 2016 : Iniciando a execução da solicitação: test-invoke-requestnThu Dec 29 08:16:05 UTC 2016 : Método HTTP: POST, Resource Path: /booksnThu Dec 29 08:16:05 UTC 2016 : Caminho da solicitação do método: {}nThu Dec 29 08:16:05 UTC 2016 : String de consulta de solicitação de método: {}nThu Dec 29 08:16:05 UTC 2016 : Method request headers: {}nThu Dec 29 08:16:05 UTC 2016 : Corpo da solicitação do método antes das transformações: {"id": "1", "nome do livro": "teste livro", "isbn": "123", "custo": "1.23"}nThu Dec 29 08:16:05 UTC 2016 : URI de solicitação de ponto final: https://lambda.us-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-1:598307997273:function:MicroservicePost/invocationsnThu Dec 29 08:16:05 UTC 2016 : Cabeçalhos de solicitação de ponto final: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************c8bb85, X-Amz-Date=20161229T081605Z, x-amzn-apigateway-api-id=lb2qgujjif, X-Amz-Source-Arn=arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/null/POST/books, Accept=application/json, User-Agent=AmazonAPIGateway_lb2qgujjif, Host=lambda.us-west-1.amazonaws.com, X-Amz-Content-Sha256=559d0296d96ec5647eef6381602fe5e7f55dd17065864fafb4f581d106aa92f4, X-Amzn-Trace-Id=Root=1-5864c645-8494974a41a3a16c8d2f9929, Content-Type=application/json}nThu Dec 29 08:16:05 UTC 2016 : Corpo da solicitação do endpoint após as transformações: {"id": "1", "nome do livro": "teste livro", "isbn": "123", "custo": "1.23"}nThu Dec 29 08:16:10 UTC 2016 : Corpo da resposta do endpoint antes das transformações: "{\"custo\":\"1.23\",\"id\":\"1\",\"nome do livro\":\"teste livro\",\"isbn\":\"123\"}"nThu Dec 29 08:16:10 UTC 2016 : Cabeçalhos de resposta do endpoint: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=0b25323b-cd9f-11e6-8bd4-292925ba63a9, Connection=keep-alive, Content-Length=78, Date=Thu, 29 Dec 2016 08:16:10 GMT, Content-Type=application/json}nThu Dec 29 08:16:10 UTC 2016 : Corpo da resposta do método após transformações: EmptynThu Dec 29 08:16:10 UTC 2016 : Cabeçalhos de resposta do método: {X-Amzn-Trace-Id=Root=1-5864c645-8494974a41a3a16c8d2f9929, Content-Type=application/json}nThu Dec 29 08:16:10 UTC 2016 : Execução concluída com sucessonThu Dec 29 08:16:10 UTC 2016 : Método concluído com status: 200n","latência": 5091,"cabeçalhos": {"X-Amzn-Trace-Id": "Root=1-5864c645-8494974a41a3a16c8d2f9929","Content-Type": "application/json"}}
Valor destatus
é 200 e indica que a invocação foi bem-sucedida. Valor deregistro
mostra a declaração de registro do CloudWatch Logs. Os registros detalhados também podem ser obtidos usandoaws logs filter-log-events --log-group /aws/lambda/MicroservicePost
. - Esse comando armazena um único documento JSON no Couchbase. Isso pode ser facilmente verificado usando o comando Ferramenta CLI do Couchbase cbqConecte-se ao servidor Couchbase como:
1cbq -u Administrador -p senha -e="http://:8091"
Criar um índice primário empadrão
pois isso é necessário para consultar o bucket sem cláusulas:
1234567891011121314cbq> criar primário índice default_index em padrão;{"requestID": "13b539f9-7fff-4386-92f4-cea161a7aa08","assinatura": nulo,"resultados": [],"status": "sucesso","métricas": {"elapsedTime" (tempo decorrido): "1.917009047s","executionTime": "1.916970061s","resultCount": 0,"resultSize": 0}} - Escreva um N1QL para acessar os dados:
123456789101112131415161718192021222324cbq> selecionar * de padrão limite 10;{"requestID": "d7b1c3f9-6b4e-4952-9a1e-9faf5169926e","assinatura": {"*": "*"},"resultados": [{"default": {"nome do livro": "teste","custo": "1.23","id": "1","isbn": "123"}}],"status": "sucesso","métricas": {"elapsedTime" (tempo decorrido): "24.337755ms","executionTime": "24.289796ms","resultCount": 1,"resultSize": 175}}
Os resultados mostram o documento JSON que foi armazenado por nossa função Lambda.
Método GET do gateway de API
Vamos criar o HTTP OBTER
no recurso:
- Criar um
OBTER
método:
12345aws apigateway colocar-método--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método OBTER--autorização-tipo NENHUM - Defina a função Lambda correta como destino do GET:
1234567aws apigateway colocar-integração--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método OBTER--tipo AWS--integração-http-método POST--uri arn:aws:apigateway:nós-oeste-1:lambda:caminho/2015-03-31/funções/arn:aws:lambda:nós-oeste-1:598307997273:função:MicroserviceGetAll/invocações - Conjunto
tipo de conteúdo
da resposta do método GET:
123456aws apigateway colocar-método-resposta--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método OBTER--status-código 200--resposta-modelos "{"aplicativo/json": "Vazio"}" - Conjunto
tipo de conteúdo
da resposta de integração do método GET:
123456aws apigateway colocar-integração-resposta--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método OBTER--status-código 200--resposta-modelos "{"aplicativo/json": "Vazio"}" - Conceder permissão para que o API Gateway invoque a função Lambda
123456aws lambda adicionar-permissão--função-nome MicroserviceGetAll--declaração-id apigateway-teste-obter tudo-1--ação lambda:InvokeFunction--principal apigateway.amazonaws.com--fonte-arn "arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/*/GET/books" - Conceder permissão à API implantada:
123456aws lambda adicionar-permissão--função-nome MicroserviceGetAll--declaração-id apigateway-teste-obter tudo-2--ação lambda:InvokeFunction--principal apigateway.amazonaws.com--fonte-arn "arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/test/GET/books" - Teste o método:
1234aws apigateway teste-invocar-método--descanso-API-id lb2qgujjif--recurso-id vrpkod--http-método OBTER
para ver a saída:
12345678910{"status": 200,"corpo": "Vazio","log": "Registro de execução da solicitação test-requestnSat Dec 31 09:07:48 UTC 2016 : Iniciando a execução da solicitação: test-invoke-requestnSat Dec 31 09:07:48 UTC 2016 : Método HTTP: GET, Caminho do Recurso: /booksnSat Dec 31 09:07:48 UTC 2016 : Caminho da solicitação do método: {}nSat Dec 31 09:07:48 UTC 2016 : String de consulta de solicitação de método: {}nSat Dec 31 09:07:48 UTC 2016 : Cabeçalhos da solicitação do método: {}nSat Dec 31 09:07:48 UTC 2016 : Method request body before transformations: nSat Dec 31 09:07:48 UTC 2016 : Endpoint request URI: https://lambda.us-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-1:598307997273:function:MicroserviceGetAll/invocationsnSat Dec 31 09:07:48 UTC 2016 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=******************************************************************************************************************************************************************************************************************************************************************************************************6de147, X-Amz-Date=20161231T090748Z, x-amzn-apigateway-api-id=lb2qgujjif, X-Amz-Source-Arn=arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/null/GET/books, Accept=application/json, User-Agent=AmazonAPIGateway_lb2qgujjif, X-Amz-Security-Token=FQoDYXdzEHEaDEILpsKTo45Ys1LrFCK3A+KOe5HXOSP3GfVAaRYHe1pDUJGHL9MtkFiPjORLFT+UCKjRqE7UFaGscTVG6PZXTuSyQev4XTyROfPylCrtDomGsoZF/iwy4rlJQIJ7elBceyeKu1OVdaT1A99PVeliaCAiDL6Veo1viWOnP+7c72nAaJ5jnyF/nHl/OLhFdFv4t/hnx3JePMk5YM89/6ofxUEVDNfzXxbZHRpTrG/4TPHwjPdoR5i9dEzWMU6Eo5xD4ldQ/m5B3RmrwpaPOuEq39LhJ8k/Vzo+pAfgJTq5ssbNwYOgh0RPSGVNMcoTkCwk0EMMT5vDbmQqZ2dW1a1tmQg9N2xR+QQy+RKMFgO5YY8fMxHnRSdMuuipxl79G1pktc [TRUNCATED]nSat Dec 31 09:07:48 UTC 2016 : Corpo da solicitação do endpoint após as transformações: nSat Dec 31 09:07:53 UTC 2016 : Corpo da resposta do endpoint antes das transformações: "[{\"padrão\":{\"custo\":\"1.23\",\"id\":\"1\",\"nome do livro\":\"teste livro\",\"isbn\":\"123\"}}]"nSat Dec 31 09:07:53 UTC 2016 : Cabeçalhos de resposta do endpoint: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=99ab09b2-cf38-11e6-996f-f5f07af431af, Connection=keep-alive, Content-Length=94, Date=Sat, 31 Dec 2016 09:07:52 GMT, Content-Type=application/json}nSat Dec 31 09:07:53 UTC 2016 : Corpo da resposta do método após transformações: EmptynSat Dec 31 09:07:53 UTC 2016 : Cabeçalhos de resposta do método: {X-Amzn-Trace-Id=Root=1-58677564-66f1e96642b16d2db703126e, Content-Type=application/json}nSat Dec 31 09:07:53 UTC 2016 : Execução concluída com sucessonSat Dec 31 09:07:53 UTC 2016 : Método concluído com status: 200n","latência": 4744,"cabeçalhos": {"X-Amzn-Trace-Id": "Root=1-58677564-66f1e96642b16d2db703126e","Content-Type": "application/json"}}
Mais uma vez, o código de status 200 mostra uma invocação bem-sucedida. Os registros detalhados podem ser obtidos usandoaws logs filter-log-events --log-group /aws/lambda/MicroservicePost
.
Este blog mostra apenas um método simples de POST e GET. Outros métodos HTTP também podem ser facilmente incluídos nesse microsserviço.
Oi @Arun,
Podemos usar o SDK do Couchbase NodeJs V2.6.3 com o lamda?
Estamos recebendo o seguinte erro quando tentamos usar o SDK mais recente.
"errorMessage": "/var/lang/lib/libstdc++.so.6: a versão `CXXABI_1.3.9′ não foi encontrada (exigida por /var/task/node_modules/couchbase/build/Release/couchbase_impl.node)",