# Kotlin - Rest Api completa com Spring Boot, Swagger, Mysql e docker #01

### Parte 01 - Configurando inicialmente nossa aplicação e a consumindo

Olá mundo! Nessa série vamos criar uma api de forma prática utilizando a linguagem Kotlin, uma linguagem moderna e estaticamente tipada bastante utilizada em aplicações android porém vem crescendo no mercado e ganhando fãs no backend javeiros, assim como eu :)
Se quiser dar os primeiros passos com o Kotlin, sugiro dar uma mergulhada na doc  [aqui](https://developer.android.com/kotlin/first?hl=pt).

Na nossa api, iremos disponibilizar os endpoints documentados com o **swagger**, criar camadas de **serviços** e **repositórios** e armazenar os dados em um **banco de dados** (Mysql no nosso exemplo) subindo a imagem com o **docker-compose**.

Antes de mais nada, vamos preparar o nosso ambiente para começarmos a criar a nossa api.

#### Dá o play!

Aqui, vou estar utilizando como IDE, o IntelliJ mas você pode utilizar a sua IDE de preferência.
Existe uma maneira fácil de criarmos o projeto já com a estrutura inicial necessária. Basta acessar:  [https://start.spring.io/](https://start.spring.io/)


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631577464843/1FVUujCN3.png)

Vamos criar uma api para realizarmos um CRUD, algo bem básico para podermos dar nosso primeiro passo. Aqui definimos o *Gradle* para automatizarmos o build e algumas *dependências* iniciais (podemos ir adicionando outras durante o desenvolvimento). Definimos o *Kotlin* como linguagem e a versão estável atual do *spring boot* e então clicamos em **Generate** para gerarmos o codigo zipado. Descompacte em sua pasta de preferência e abra o projeto em sua IDE.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631577990363/oTT6pwsjJ.png)

Ao abrir o projeto, o build do Gradle irá entrar em ação e começara a baixar as dependências do projeto. Aguarde a conclusão do build e mão na massa!

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631578135924/r9apFx6Sv.png)

Primeiro, vamos precisar configurar nosso arquivo *docker-compose.yml* para subirmos uma imagem do Mysql. Crie na pasta raiz do projeto (crudexample) um arquivo chamado docker-compose.yml com o seguinte conteúdo:

```
version: '3.1'
services:
  db:
    container_name: mysql_local
    image: mysql:5.7
    volumes:
      - ./db:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
      MYSQL_ROOT_PASSWORD: "test"
      MYSQL_DATABASE: "crudexample"
      MYSQL_USER: "admin"
      MYSQL_PASSWORD: "test"
      MYSQL_ROOT_HOST: "%"
    ports:
      - "1000:3306"
``` 
Caso ainda não tenha instalado, para poder continuar iremos precisar do docker-compose, veja  [aqui](https://docs.docker.com/compose/install/) como instalar de acordo com a versão do seu sistema operacional.

Se preferir, pode alterar os dados *MYSQL_USER* e *MYSQL_PASSWORD* para sua preferência.
Com o arquivo criado, podemos subir a imagem do docker com o seguinte comando em seu terminal
`docker-compose up -d` e subindo corretamente, conseguimos listar as imagens com o comando `docker ps`

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631582517386/TcUFJZsUa.png)

Feito isso, já temos nosso mysql 'em pé' :)
Vamos agora configurar as propriedades da aplicação. Você irá notar que em `src > main > resources` irá existir um arquivo (sem nenhuma informação) chamado application.properties. Aqui você pode definir alguns valores para sua aplicação. Eu prefiro trabalhar com arquivo yml, então podemos renomear esse arquivo ou criar um novo chamado `application.yml`
```
server:
  port: 8081
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    initialization-mode: always
    password: test
    platform: mysql
    url: jdbc:mysql://localhost:1000/crudexample
    username: admin
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
    database-platform: org.hibernate.dialect.PostgreSQLDialect
    generate-ddl: true
    show-sql: true
    hibernate:
      ddl-auto: update
      naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
```
Aqui configuramos a porta da nossa aplicação e as propriedades do nosso banco de dados. Irei detalhar melhor em outro momento, mas nossa aplicação já poderá subir localmente e iremos verificar se ela está 'on'. Para isso, rodamos em nossa IDE o `CrudexampleApplication.kt` em `src > main > kotlin > com.kotlin.crudexample` e então, nosso Run terá a mensagem de que a aplicação está rodando na porta 8081 e a mensagem de inicialização `Started CrudexampleApplicationKt in 5.87 seconds (JVM running for 6.9)`.

Para testarmos se a aplicação de fato está 'viva', vamos contar com a mágica do actuator, acessando o endereço `http://localhost:8081/actuator` e um json deve ser exibido indicando o caminho do health e que nossa aplicação está rodando perfeitamente.

Caso tenha ocorrido algum problema até esse caminho, fique a vontade em me contatar para analisarmos o que pode ter ocorrido.

#### Aplicação configurada, vamos brincar!

Agora sim, vamos ao que interessa (nada de hello world por aqui!) e vamos começar a desenvolver uma aplicação básica que poderá ser utilizada como um start na sua empresa ou para seus estudos em api's utilizando kotlin. A ideia é fazermos uma api onde iremos cadastrar produtos, alterar, deletar e exibir para o cliente. A partir daí, o céu é o limite! Mas lembre-se sempre do conceito de micro-serviços :) 

Vamos começar com a 'controller', e lembrando que ao decorrer do conteúdo vamos refatorando as classes conforme necessário. Criaremos um package chamado `controller` e dentro dele uma classe Kotlin `ProductController` com o seguinte conteúdo:
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631642235987/C1h8MiYzJ.png)
```
package com.kotlin.crudexample.controller

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class ProductController {

    @GetMapping("/products")
    fun getAll(): List<String> = listOf("product1", "product2")
}
```
Aqui, nós estamos usando annotations do spring para nos auxiliar. O `@RestController` deverá ser anotado na classe controller de Produto para que a aplicação entenda que estamos trabalhando com Rest. Nosso primeiro método, vamos trazer uma lista de produtos, para isso usamos a anotação `@GetMapping` e setamos um *path* para ele. Seguindo o exemplo, toda vez que eu acessar nossa aplicação /products iremos retornar o conteúdo da função `getAll()`. Para facilitar e entendermos o que acontece, criamos uma lista do tipo `String` e retornamos dois itens dentro dessa lista.

No Kotlin, podemos ter uma função (método) mais clean. Inicializamos o nome da função com `fun getAll()` e indicamos qual sera o tipo de retorno `: List<String>`. Se precisamos apenas retornar o conteúdo, algo que fazemos da seguinte maneira no Java:
```
public List<String> getAll() {
 return ...conteudo
}
```
Em Kotlin, basta usarmos o `=` e teremos o nosso return, como nosso exemplo
```
fun getAll(): List<String> = ...conteudo
```

Então, seguindo o que fizemos até aqui, com a aplicação rodando podemos já consumir nosso primeiro endpoint acessando `http://localhost:8081/products` e iremos ter o retorno `["product1","product2"]`.

Agora que entendemos um pouco melhor do nosso controller, vamos aperfeiçoar o que já foi feito e separarmos algumas responsabilidades. Em nosso próximo post, iremos contruir nosso `Repository` e nosso `Service` para podermos consumir os dados em nosso `Controller`.

Vejo vocês no próximo post, acessando esse link:  [https://rafaelmoura.dev/kotlin-rest-api-completa-02](https://rafaelmoura.dev/kotlin-rest-api-completa-02) 

O repositório do código estará disponível [aqui](https://github.com/rafmoura25/rafaelmoura.dev) , e irei separar por post para ficar mais fácil :)

Espero que esteja curtindo até aqui. Dúvidas, sugestões, melhorias? Comenta aí ou fica a vontade para mandar uma mensagem!


 
