Introdução ao desenvolvimento de backend em Kotlin usando Spring Boot 3 e MongoDB
Avalie esse Tutorial
Este é um artigo de introdução sobre como criar um aplicativo RESTful no Kotlin usando oSpring Boot 3 e oMongoDB Atlas.
Hoje, vamos construir um aplicativo RESTful básico que faz um pouco mais de uma operação CRUD e, para isso, usaremos:
Spring Boot 3
que é uma das estruturas populares baseadas no Spring, permitindo que os desenvolvedores criem classes de produção rapidamente.MongoDB
, que é um banco de dados orientado a documentos, permitindo que os desenvolvedores se concentrem na criação de aplicativos em vez de no esquema do banco de dados.
Para ajudar nas atividades de desenvolvimento, usaremos o Jetbrains IntelliJ IDEA (Community Edition).
Criar um aplicativo HelloWorld em qualquer linguagem/tecnologia de programação, acredito, é a maneira mais rápida e fácil de se familiarizar com ela. Isso ajuda você a cobrir os conceitos básicos, como como construir, executar, depurar, implantar etc.
Como estamos usando a versão comunidade do IDEA, não podemos criar o projeto
HelloWorld
diretamente do próprio IDE usando o Novo Projeto. Mas podemos usar o aplicativo inicializador Spring, que nos permite criar um projeto Spring pronto para uso.Quando estiver no site, você pode atualizar os parâmetros selecionados padrão para o projeto, como o nome do projeto, idioma, versão do
Spring Boot
etc., para algo semelhante, conforme mostrado abaixo.E como queremos criar uma REST API com o MongoDB como banco de dados, vamos adicionar a dependência usando o botão Adicionar dependência à direita.
Depois de todas as atualizações, as configurações do nosso projeto ficarão assim.
Agora podemos baixar a pasta do projeto usando o botão gerar e abri-la usando o IDE. Se examinarmos a pasta do projeto, encontraremos apenas uma classe - ou seja,
HelloBackendWorldApplication.kt
, que também tem a funçãomain
.O próximo passo é imprimir OláMundo na tela. Como estamos criando um aplicativo restful, criaremos uma API de solicitação
GET
. Então, vamos adicionar uma função para atuar como uma chamada de APIGET
.1 2 fun hello( name: String?): String { 3 return String.format("Hello %s!", name) 4 }
Também precisamos adicionar uma anotação de
@RestController
ao nosso class
para torná-lo um clienteRestful
.1 2 3 class HelloBackendWorldApplication { 4 5 fun hello(): String { 6 return "Hello World!" 7 } 8 } 9 10 fun main(args: Array<String>) { 11 runApplication<HelloBackendWorldApplication>(*args) 12 }
Agora, vamos executar nosso projeto usando o ícone de execução na barra de ferramentas.
Agora carregue https://localhost:8080/hello no navegador quando a construção for concluída, e isso imprimirá Olá, mundo na sua tela.
E, ao fazer a validação cruzada disso com o Postman, podemos entender perfeitamente que nossa API
Get
está funcionando perfeitamente.É hora de entender os fundamentos do
Spring Boot
que facilitaram tanto a criação de nossa primeira chamada de API.De acordo com os Docs, o Spring Boot facilita a criação de aplicativos autônomos, de nível de produção e baseados em Spring que você pode "simplesmente executar".
Isso implica que é uma ferramenta construída sobre a estrutura Spring, permitindo-nos construir aplicativos da web rapidamente.
Spring Boot
usa anotações, que fazem o trabalho pesado em segundo plano. Alguns deles já usamos, como:@SpringBootApplication
: esta anotação é marcada no nível da classe e declara ao leitor de código (desenvolvedor) e ao Spring que é um projeto do Spring Boot. Permite um recurso de ativação, que também pode ser feito utilizando@EnableAutoConfiguration
,@ComponentScan
e@Configuration
.@RequestMapping
e@RestController
: esta anotação fornece as informações de roteamento. O roteamento nada mais é do que um mapeamento de um caminho de solicitaçãoHTTP
(texto apóshost/
) para classes que têm a implementação deles em vários métodosHTTP
.
Essas anotações são suficientes para criar um aplicativo básico. Usando o Spring Boot, criaremos um serviço web RESTful com toda a lógica de negócios, mas não temos um contêiner de dados que possa armazenar ou fornecer dados para executar essas operações.
Para nosso aplicativo, usaremos MongoDB como banco de dados. O MongoDB é um banco de dados de documentos distribuído, multiplataforma e open source, que permite criar aplicativos com esquema flexível. Isso é ótimo porque podemos nos concentrar na construção do aplicativo em vez de definir o esquema.
Podemos começar a usar o MongoDB muito rapidamente usando o MongoDB Atlas, que é um banco de dados como serviço na nuvem e tem uma camada gratuita para sempre.
Recomendamos que você navegue nasérie MongoDB Saltode início para se familiarizar com o MongoDB e seus vários serviços em menos 10 minutos.
Com os fundamentos do MongoDB cobertos, agora vamos conectar nosso projeto Spring Boot a ele. Conectar-se com o MongoDB é muito simples, graças ao plug-in Spring Data MongoDB.
Para se conectar ao MongoDB Atlas, precisamos apenas de um URL de bancode dados que possa ser adicionado como uma propriedade
spring.data.mongodb.uri
no arquivoapplication.properties
. A string de conexão pode ser encontrada como mostrado abaixo.O formato para a string de conexão é:
1 spring.data.mongodb.uri = mongodb + srv ://<username>:<pwd>@<cluster>.mongodb.net/<dbname>
Com todos os fundamentos abordados, agora vamos criar um aplicativo mais complexo do que o OláMundo! Neste aplicativo, abordaremos todas as operações CRUD e as ajustaremos ao longo do caminho para torná-lo um aplicativo mais realista. Então, vamos criar um novo projeto semelhante ao aplicativo OláMundo que criamos anteriormente. E para este aplicativo, usaremos um dos conjuntos de dados de amostra fornecidos pelo MongoDB — um dos meus recursos favoritos que permite o aprendizado rápido.
Usaremos a coleção
sample_restaurants
para nosso aplicativo CRUD. Antes de começarmos com a operação CRUD real, vamos criar a classe de modelo de restaurante equivalente a ela na coleção.1 2 data class Restaurant( 3 4 val id: ObjectId = ObjectId(), 5 val address: Address = Address(), 6 val borough: String = "", 7 val cuisine: String = "", 8 val grades: List<Grade> = emptyList(), 9 val name: String = "", 10 11 val restaurantId: String = "" 12 ) 13 14 data class Address( 15 val building: String = "", 16 val street: String = "", 17 val zipcode: String = "", 18 19 val coordinate: List<Double> = emptyList() 20 ) 21 22 data class Grade( 23 val date: Date = Date(), 24 25 val rating: String = "", 26 val score: Int = 0 27 )
Você notará que não há nada de especial nessa classe, exceto a anotação. Essas anotações nos ajudam a conectar ou correlacionar classes com bancos de dados como:
@Document
: Isto declara que esta classe de dados representa um documento no Atlas.@Field
: é usado para definir um nome alternativo para uma propriedade no documento, comocoord
para coordenadas no modeloAddress
.
Agora vamos criar uma classe de repositório onde podemos definir todos os métodos através dos quais podemos acessar os dados.
Spring Boot
tem a interface MongoRepository
, o que nos ajuda com isso.1 interface Repo : MongoRepository<Restaurant, String> { 2 3 fun findByRestaurantId(id: String): Restaurant? 4 }
Depois disso, criamos um controlador por meio do qual podemos chamar essas consultas. Como este é um projeto maior, ao contrário do aplicativo HelloWorld, criaremos um controlador separado em que a instância
MongoRepository
é passada usando@Autowired
, que fornece injeção de dependência orientada por anotações.1 2 3 class Controller( val repo: Repo) { 4 5 }
Agora que nosso projeto está pronto para realizar alguma ação, vamos contar o número de restaurantes na coleção usando
GetMapping
.1 2 3 class Controller( val repo: Repo) { 4 5 6 fun getCount(): Int { 7 return repo.findAll().count() 8 } 9 }
Dando mais um passo para ler o
restaurantId
baseado em restaurantes. Vamos ter que adicionar um método em nosso repositório, pois restaurantId
não está marcado @Id
na classe do restaurante.1 interface Repo : MongoRepository<Restaurant, String> { 2 fun findByRestaurantId(restaurantId: String): Restaurant? 3 }
1 2 fun getRestaurantById( id: String): Restaurant? { 3 return repo.findByRestaurantId(id) 4 }
E, novamente, usaremos o Postman para validar a saída em relação a um
restaurantId
aleatório do conjunto de dados de amostra.Vamos também validar isso em relação a um
restaurantId
inexistente.Como esperado, não obtivemos nenhum resultado, mas o código de resposta da API ainda é 200, o que está incorreto! Então, vamos corrigir isso.
Para ter o código de resposta correto, teremos que verificar o resultado antes de enviá-lo de volta com o código de resposta correto.
1 2 fun getRestaurantById( id: String): ResponseEntity<Restaurant> { 3 val restaurant = repo.findByRestaurantId(id) 4 return if (restaurant != null) ResponseEntity.ok(restaurant) else ResponseEntity 5 .notFound().build() 6 }
Para adicionar um novo objeto à collection, podemos adicionar uma função
write
no repo
que criamos anteriormente ou podemos usar o método incorporado insert
fornecido por MongoRepository
. Como adicionaremos um novo objeto à collection, usaremos @PostMapping
para isso.1 2 fun postRestaurant(): Restaurant { 3 val restaurant = Restaurant().copy(name = "sample", restaurantId = "33332") 4 return repo.insert(restaurant) 5 }
A Spring não tem nenhuma atualização embutida específica semelhante a outras operações CRUD, portanto, usaremos a operação de leitura e gravação combinada para executar a função de atualização.
1 2 fun updateRestaurant( id: String): Restaurant? { 3 return repo.findByRestaurantId(restaurantId = id)?.let { 4 repo.save(it.copy(name = "Update")) 5 } 6 }
Essa não é uma maneira ideal de atualizar itens na coleção, pois requer duas operações e pode ser melhorada se usarmos o driver nativo do MongoDB, que nos permite realizar operações complicadas com o número mínimo de etapas.
A exclusão de um restaurante também é semelhante. Podemos usar a função
MongoRepository
exclusão do item da collection, que usa o item como entrada.1 2 fun deleteRestaurant( id: String) { 3 repo.findByRestaurantId(id)?.let { 4 repo.delete(it) 5 } 6 }
Grato por ler e esperemos que você ache este artigo informativo! O código fonte completo do aplicativo pode ser encontrado no GitHub.
Se você tiver alguma dúvida ou comentário, pode compartilhá-los no fórum do MongoDB ou enviar um tweet para mim @codeWithMohit.