Criando uma API com Spring Boot e Kotlin — parte 2
Seguindo nossa série de posts sobre como construir uma API simples para servir de back-end para um app de construção de setups de PC que criamos há algum tempo, hoje vamos escrever nossas classes models, configurar nosso banco de dados e implementar as requisições GET e POST do nosso serviço.
Criando classes models
Para representar um Setup com todas as suas peças vamos precisar de duas entidades: Part
, para representar uma peça, e Setup
, para representar um Setup.
Código da classe Part:
É uma classe bem simples composta por propriedades para representar seu titulo, descrição, url e valor. Também temos a propriedade id
que é autogerada. A notação de mesmo nome indica que propriedade é um identificador no banco de dados, GeneratedValue
significa que seu valor será gerado ao ser criada uma instância dessa entidade, JsonProperty
, em resumo, protege a propriedade identificadora de ser alterada. Além disso, a notação Entity
indica que essa classe é a representação de uma entidade do banco de dados.
Código da classe Setup:
A classe Setup é composta por várias classes Part, cada uma representando uma peça. Temos também a propriedade totalValue
que retorna o valor total do setup, sendo composto pela soma dos valores de todas as peças.
Em relação às anotações, temos algumas novas aqui:
OneToOne
: indica que a relação entre a entidadeSetup
e essa outra entidade específica é de 1:1, ou seja, um setup tem apenas uma entidade dessa.OneToMany
: indica que a relação entre a entidadeSetup
e essa outra entidade é de 1:N, ou seja, um setup pode ter várias dessa entidade.cascade = [CascadeType.PERSIST]
: significa que a operação de persistência será persistida de pai para filho, ou seja, sempre que um setup for salvo, todas as suas peças também serão.
Pronto: já temos nossas entidades da camada model
.
Configurando o banco de dados
A configuração do nosso banco de dados será bem simples, primeiro nos vamos renomear o arquivo application.properties
para application.yaml
e escrever o seguinte:
Aqui temos uma sopa de letrinhas, vamos lá:
spring:datasource:url
: é o endereço do banco de dados que será utilizadospring:datasource:username
: é o nome do usuário do banco de dadosspring:datasource:driver-class-name
: é o driver que permite a comunicação entre nossa aplicação e o HSQLDBjpa:properties.hibernate.dialect
: indica que o SQL vai reconhecer o HSQLDBjpa:properties.hibernate.dialect
: indica ao Hibernate que ele deve gerar as tabelas de acordo com as entidades do ORM
Para finalizar a configuração do banco, vamos viabilizar o nosso CRUD, para isso vamos criar uma interface que estenda de CrudRepository
do Spring Data:
Parece até mentira, mas é só isso mesmo: delegamos toda a tarefa de persistir os dados, criar um repositório, injetar a dependência para o Spring e já temos acesso a funções como findAll()
e save()
que logo usaremos.
Requisições GET e POST
Agora basta implementar as funções GET
e POST
para finalizar nosso trabalho de hoje, para isso vamos criar uma classe controller. Uma classe Controller
em Spring é uma classe responsável por lidar com requisições web.
Segue nossa SetupController
:
Logo no início usamos duas novas notações: @RestController
, significa que nossa classe é um controller que atende à uma API REST, @RequestMapping
, indica qual o caminho da url que esse controller está mapeando.
Depois nós delegamos a injeção da dependência do nosso repositório para o Spring por meio do @Autowired
. Repare que a propriedade é uma lateinit var
, ou seja, ela será inicializada no futuro.
Por fim, finalmente temos a implementação dos nossos métodos GET e POST.
Nosso método GET é bem simples, ele retorna todos os Setup
salvos no nosso banco de dados por meio do método findAll()
, depois convertemos o resultado para o tipo List<Setup>
. Como é um método GET, usamos a notação @GetMapping
, indicando que o método mapeia esse tipo de requisição.
Quanto ao nosso método POST, ele recebe um Setup
por meio do corpo (body) da requisição, por isso usamos a notação @RequestBody
para mapear a propriedade, é salvo e retornamos esse Setup salvo no banco de dados usando a função save()
. Do mesmo modo, usamos a notação @PostMapping
, para indicar que o método mapeia uma requisição POST.
Agora sim, já podemos testar nossa API!
Testando a API
Para começar, vamos testar a função que mapeia a requisição POST. Mandamos esse seguinte JSON para a nossa API usando o Postman
:
E temos esse resultado:
Repare que todos os IDs foram criados, para cada entidade, e também temos o valor total do Setup na chave-valor totalValue
.
Vamos usar novamente essa requisição mandando esse json (praticamente igual ao anterior):
E temos o seguinte resultado:
E finalmente vamos usar a requisição GET:
E assim, os dois setups criados foram retornados com sucesso!
Próximos posts
Nossa API ainda tem muito o que melhorar: ainda precisamos implementar os métodos PUT e DELETE, melhorar sua segurança e adicionar testes. Vamos fazer isso nós próximos dois posts.
Post anterior:
Próximo post:
Repo no github:
Obrigado pela atenção e até a próxima!