Olá pessoal, tudo bem?
Seguindo a nossa série em que vamos criar um CRUD Serverless com Azure Functions, hoje desenvolveremos a parte de edição e de exclusão do nosso registro.
Primeiramente vamos trabalhar na edição, e portanto, começaremos criando nossa Function através do comando abaixo:
func new
Feito isso, como já é sabido, aparecerão diversas opções de Azure Functions, cada uma para um propósito diferente, e no nosso caso escolheremos o tipo HttpTrigger e então nós daremos a ela o nome de EditPerson.
Abra o arquivo criado (EditPerson.cs) e vamos altera-lo com o código abaixo:
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "put", Route = null)]HttpRequest req,
[Queue("EditPerson", Connection = "AzureWebJobsStorage")]IAsyncCollector<string> queueItem,
ILogger log)
{
log.LogInformation("EditPerson function started a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
await queueItem.AddAsync(requestBody);
log.LogInformation("EditPerson function finished a request.");
return new OkObjectResult($"Obrigado! Seu registro já esta sendo processado.");
}
Observe que o código não é muito diferente do código da nossa HttpTrigger que criamos na parte 1 do nosso post.
Dica: Observe que na chamada da nossa HttpTrigger existe uma propriedade chamada Route, ela serve para customizarmos a rota da nossa Function caso você queira, do contrário o padrão será sempre o nome da sua HttpTrigger.
Vamos agora executar nosso Function App utilizando o comando abaixo:
func start
Note que agora nós temos dois endpoints: CreatePerson: [POST] http://localhost:7071/api/CreatePerson e EditPerson: [PUT] http://localhost:7071/api/EditPerson e com isso já é possível testar nossa função de edição (para isso recomendo utilizar um Client REST da sua preferência), porém dessa vez precisaremos passar além das propriedades Name e Email as propriedades para encontrar o registro em si e elas são a PartitionKey e o RowKey. Com isso seu body deve ficar muito parecido com que se encontra logo abaixo:
{
"name": "Blog do Ericson - Edit",
"email": "ericson@email.com",
"partitionKey": "Person",
"rowKey": "<GUID_DO_REGISTRO>"
}
Feito isso abra a ferramenta Microsoft Azure Storage Explorer e localize dentro de Storage Account o serviços de Queues e abrindo-o note que foi criada uma Queue chamada EditPerson. Abra a mesma e note que o body que passamos para o nosso endpoint estará armazenado na fila.
Agora nosso próximo passo, assim como na parte 1 do nosso post, será o de desenfileirar a mensagem e salva-la no nosso banco de dados e para isso vamos criar nossa próxima Azure Function, e para isso, novamente vamos utilizar o comando abaixo:
func new
Dessa vez escolheremos o tipo QueueTrigger e colocaremos o nome dela de EditPersonQueue e em seguida, vamos altera-la com o código abaixo:
public static void Run(
[QueueTrigger("EditPerson", Connection = "AzureWebJobsStorage")]string queueItem,
[Table("Person")]CloudTable cloudTable,
ILogger log)
{
log.LogInformation($"EditPersonQueue trigger function started.");
var data = JsonConvert.DeserializeObject<Person>(queueItem);
var tableOperation = TableOperation.InsertOrReplace(data);
cloudTable.ExecuteAsync(tableOperation);
log.LogInformation($"EditPersonQueue trigger function finished.");
}
Note que novamente não há muita mudança em relação nossa Queue Trigger criada no post anterior.
Com isso vamos executar nosso Function App novamente através do comando:
func start
E então abra novamente o Microsoft Azure Storage Explorer e note que a mensagem sumiu da fila EditPerson, e agora o registro encontra-se editado na nossa tabela Person.
Agora que a edição esta finalizada e funcionando perfeitamente, vamos para o próximo passo que é o de excluir o nosso registro, e para isso vamos novamente criar mais uma função através do comando abaixo:
func new
Novamente, escolha o tipo HttpTrigger e então nós daremos a ela o nome de DeletePerson.
Abra o arquivo criado (DeletePerson.cs) e vamos altera-lo com o código abaixo:
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "delete", Route = null)]HttpRequest req,
[Queue("DeletePerson", Connection = "AzureWebJobsStorage")]IAsyncCollector<string> queueItem,
ILogger log)
{
log.LogInformation("DeletPerson function started a request.");
await queueItem.AddAsync(
JsonConvert.SerializeObject(
new Person
{
PartitionKey = "Person",
RowKey = req.Query["id"]
}
)
);
log.LogInformation("DeletePerson function finished a request.");
return new OkObjectResult($"Obrigado! Seu registro já esta sendo processado.");
}
Observe que agora nossa HttpTrigger, ao contrario das criadas anteriormente, espera como body apenas o Partition Key (coloquei ele já direto no código, mas você pode passa-lo como parâmetro caso queira) e o RowKey que será passado via QueryString sob o parâmetro de nome id.
Vamos agora executar nosso Function App utilizando o comando abaixo:
func start
Note que agora nós temos três endpoints: DeletePerson: [DELETE] http://localhost:7071/api/DeletePerson, CreatePerson: [POST] http://localhost:7071/api/CreatePerson e EditPerson: [PUT] http://localhost:7071/api/EditPerson e com isso já é possível testar nossa função de exclusão (para isso recomendo utilizar um Client REST da sua preferência), porém dessa vez conforme precisaremos apenas do RowKey e com isso sua QueryString deve ficar muito parecido com que se encontra logo abaixo:
http://localhost:7071/api/DeletePerson?id=<GUID_DO_REGISTRO>
Feito isso abra a ferramenta Microsoft Azure Storage Explorer e localize dentro de Storage Account o serviços de Queues e abrindo-o note que foi criada uma Queue chamada DeletePerson. Abra a mesma e note que o body que passamos para o nosso endpoint estará armazenado na fila.
Agora nosso próximo passo, assim como na parte 1 do nosso post, será o de desenfileirar a mensagem e salva-la no nosso banco de dados e para isso vamos criar nossa próxima Azure Function, e para isso, novamente vamos utilizar o comando abaixo:
func new
Dessa vez escolheremos o tipo QueueTrigger e colocaremos o nome dela de DeletePersonQueue e em seguida, vamos altera-la com o código abaixo:
public static void Run(
[QueueTrigger("DeletePerson", Connection = "AzureWebJobsStorage")]string queueItem,
[Table("Person")]CloudTable cloudTable,
ILogger log)
{
log.LogInformation($"DeletePersonQueue trigger function started.");
var data = JsonConvert.DeserializeObject<Person>(queueItem);
var person = new DynamicTableEntity(data?.PartitionKey, data?.RowKey);
person.ETag = "*";
var tableOperation = TableOperation.Delete(person);
cloudTable.ExecuteAsync(tableOperation);
log.LogInformation($"DeletePersonQueue trigger function finished.");
}
Note que dessa vez houve uma certa mudança em relação nossa Queue Trigger criada no post anterior.
Aqui nos primeiros temos que recuperar o registro da nossa Table Person, baseando-se na PartitionKey e no RowKey antes de mais nada e na sequência setar a propriedade ETag. Falando rapidamente sobre essa propriedade, ela consegue atuar no caso de concorrência de alterações de um registro, como aqui eu quero excluir o mesmo eu estou setando com o * e isso significa que eu estou dizendo para o Tables não se preocupar em monitorar essa exclusão.
Com isso vamos executar nosso Function App novamente através do comando:
func start
E então abra novamente o Microsoft Azure Storage Explorer e note que a mensagem sumiu da fila DeletePerson, e agora o registro também não existe mais na nossa tabela Person.
Bom pessoal, e com isso finalizamos a segunda parte do nosso CRUD Serverless em que editamos e excluímos o nosso registro. No nosso próximo post vamos trabalhar na exibição dos registros já cadastrados e na publicação do nosso Function App no Azure.
E para finalizar deixo aqui um convite.
Que tal aprender mais sobre Docker, Kubernetes e a implementação de soluções baseadas em containers utilizando o Microsoft Azure, em um workshop que acontecerá durante um sábado todo (dia 04/04) em São Paulo Capital e implementando um case na prática?
Acesse então o link a seguir para efetuar sua inscrição (já incluso camiseta, emissão de certificado e almoço para os participantes) com o desconto: http://bit.ly/anp-docker-blog-ericson
Até mais pessoal.
Abraços e Obrigado!