ASP.NET Web API: Criando um web service com várias entidades
Neste exemplo veremos como desenvolver um web service RESTful com ASP.NET Web API que contará com as funções de CRUD com relacionamento 1:N. Além disso poderemos também efetuar filtros e ordenação com OData.
Projeto já adicionado aos favoritos. Clique aqui para ver todos seus favoritos
Obrigado pela sua avaliação, deixe o seu feedback nos comentários :D
Apresentação
Web Service RESTful com várias entidades
Neste exemplo desenvolveremos um web service para cadastro de empresas e suas vagas de emprego. Cada vaga está relacionada a uma empresa e possui vários requisitos, o que caracteriza relacionamentos do tipo 1:N entre as entidades Vaga e Empresa e Vaga e Requisito.
As seguintes tecnologias foram empregadas no desenvolvimento dessa solução:
- ASP.NET Web API: framework para criação de web services RESTful no .NET Framework;
- Entity Framework: framework de Mapeamento Objeto-Relacional que será usado para acessar o banco de dados SQL Server;
- Fluent API: conjunto de classes do Entity Framework por meio das quais é possível configurar o Mapeamento Objeto-Relacional sem usar Data Annotations, mantendo essa tarefa isolada em uma classe;
- FluentValidation: biblioteca gratuita e de código aberto para realização de validações em classes usando Lambda Expressions. Neste exemplo essa biblioteca será utilizada para substituir as Data Annotations e superar limitações destas;
- OData: protocolo para criação de web services com listagem, paginação, filtro, ordenação e seleção de campos a partir da URL.
Verbos e códigos do HTTP
Nesse web service empregaremos os verbos do protocolo HTTP da forma como eles têm sido mais adotados no mercado para a construção desse tipo de solução. A Figura 1 ilustra a função para a qual cada verbo HTTP será utilizado no nosso serviço.
Figura 1. Relação entre os verbos HTTP e as ações do web service
Além disso utilizaremos também os códigos de status previstos pelo protocolo HTTP para indicar o resultado das requisições, da seguinte forma:
Requisições bem-sucedidas:
- 200 OK: para requisições do tipo GET bem-sucedidas, em que um ou mais registros são listados;
- 201 Created: para requisições POST bem-sucedidas, quando um novo registro é cadastrado;
- 204 No Content: para requisições PUT e DELETE bem-sucedidas, quando a operação foi realizada com sucesso, mas não precisamos retornar nenhum dado adicional para o cliente.
- Requisições com problema:
- 400 Bad Request: para requisições com parâmetros inválidos. Por exemplo, quando o cliente tentar cadastrar um registro que não seja aprovado na validação;
- 401 Unauthorized: para requisições POST, PUT e DELETE que não incluam o cabeçalho de autenticação, pois esses métodos serão restritos apenas para usuários autorizados;
- 404 Not Found: para requisições GET, PUT e DELETE em que o registro solicitado não for localizado no banco de dados (filtrando pelo id).
Além desses códigos que serão gerenciados por nós, o próprio framework já retorna o código 500 Internal Server Error em caso de erros não tratados.
Listagem de dados
A listagem de dados no nosso web service será feita por meio de requisições GET na URL /api/vagas ou /api/empresas. Nesse contexto temos algumas possibilidades para obter os dados da forma que preferirmos usando o OData:
?$filter={filtro}: aplica filtros diversos seguindo do protocolo OData. Abaixo temos alguns exemplos de filtro que podem ser aplicados:
$filter=Propriedade eq Valor |
Registros cuja “Propriedade” seja igual a “Valor”. |
$filter=Propriedade gt Valor |
Registros cuja “Propriedade” seja maior que (greater than) “Valor”. |
$filter=Propriedade lt Valor |
Registros cuja “Propriedade” seja menor que (less than) “Valor”. |
$filter=substring('Valor', Propriedade) |
Registros cuja “Propriedade” contenha o texto “Valor”. |
A lista completa de operadores disponíveis pode ser encontrada na documentação oficial do OData.
?$orderby={propriedades}: ordena o resultado a partir de uma ou várias propriedades, de forma crescente ou decrescente. Abaixo temos exemplos de ordenação:
$orderby=Salario
|
Ordena pelo campo Salario de forma crescente. |
$orderby=Salario, Id desc |
Ordena pelo campo Salario de forma crescente e pelo campo Id de forma decrescente. |
?$select={propriedades}: define quais campos devem ser retornados no registro. Essa opção é particularmente útil para aplicações clientes que não precisam listar todos os dados do resultado na requisição. Para isso, é possível escolher apenas os campos que são úteis em cada contexto. Abaixo temos um exemplo de uso desse parâmetro:
$select=Titulo, Salario |
Lista apenas os campos Titulo e Salario. |
Além dessas opções de requisição que retornam vários registros temos a opção de buscar um registro específico pelo seu id:
GET /api/vagas/{id}: retorna um único registro com status 200, filtrando-o pelo id. Caso o id informado na URL seja menor que zero, o servidor responderá com um status 400. Já se o id informado não corresponder a nenhum registro, será retornado o status 404.