
https://discord.gg/35cmPpAdkG
implementation("io.insert-koin:koin-logger-slf4j:3.5.1")
USER_NOT_LOGGED_IN("Não foi possível obter o usuário logado")
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlin_version") testImplementation("io.ktor:ktor-server-test-host-jvm")
"zK2GCfKQtRQDPVnpDSB5Sk=ra7BTxZ?sLDkLDi6XdGcgU/iZLm3tN3mrpwxrhzZ?KvZmCrW1eQk=/x!z-7N" + "qq8HqQo5Gi?NCEJbuooC5uZKHN1P0CsQvnQXjmXGv!iz/eqJr6KoYW?ylVBhnh5lVpQfxJB7UagAnZ=" + "YswqxqNwAzNt-b0sLtqxfTZQrVSqT-acrz0?BIVcusWnVH8sWO?M/-M9A5jvmf0LDYxPBb86zu6X!idN-f/R/2bzYfF8br"
const val FAKE_PASSWORD_HASHED = "5f4dcc3b5aa765d61d8327deb882cf9922”
const val FAKE_PASSWORD_HASHED = "5f4dcc3b5aa765d61d8327deb882cf9922”
database_name = ${?DATABASE_NAME}
mongodb_uri_local = ${?MONGODB_URI_LOCAL}
mongodb_uri_remote = ${?MONGODB_URI_REMOTE} }
implementation("io.ktor:ktor-client-auth-jvm")
implementation("io.ktor:ktor-client-content-negotiation-jvm")
enum class CategoryEnum(val value: Int, val description: String) {
Breakfast(0, "Café da Manhã"),
Lunch(1, "Almoço"),
Dessert(2, "Sobremesa"),
Snack(3, "Lanche"),
Dinner(4, "Jantar");
companion object {
fun fromInt(value: Int) = entries.first { it.value == value }
}
}
return when {
userId.isNullOrEmpty() -> SimpleResponse(
isSuccessful = false,
message = ErrorCodes.USER_ID_NOT_FOUND.message
)
request.name.isEmpty() -> SimpleResponse(
isSuccessful = false,
message = ErrorCodes.TITLE_REQUIRED.message
)
request.category < 0 -> SimpleResponse(
isSuccessful = false,
message = ErrorCodes.CATEGORY_REQUIRED.message
)
request.preparationTime.isEmpty() -> SimpleResponse(
isSuccessful = false,
message = ErrorCodes.PREPARATION_TIME_REQUIRED.message
)
request.preparationMode.isEmpty() -> SimpleResponse(
isSuccessful = false,
message = ErrorCodes.PREPARATION_MODE_REQUIRED.message
)
request.ingredients.isEmpty() -> SimpleResponse(
isSuccessful = false,
message = ErrorCodes.INGREDIENTS_REQUIRED.message
)
else -> SimpleResponse(
isSuccessful = true,
message = SuccessCodes.VALID_REGISTRATION.message
)
}
Melhor explicação sobre o return@get
o uso de return@get é uma forma de retorno rotulado em Kotlin. Isso é necessário porque a função get(PATH_SEARCH) utiliza uma expressão lambda como argumento. Em Kotlin, a instrução return dentro de uma lambda, por padrão, tenta retornar da função mais externa que a contém. Para retornar especificamente de dentro da lambda, usamos um rótulo com o símbolo @, seguido pelo nome da função que recebe a lambda, neste caso, get. Assim, return@get garante que o retorno ocorra apenas dentro do escopo da lambda passada para get, sem afetar a função externa que a contém.
Deixei o link para vocês darem uma olhada sobre como o roteamento funciona com lambdas no Ktor
INVALID_REQUEST_ERROR("Requisição inválida. Por favor, verifique os dados enviados."),
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.junit.platform:junit-platform-launcher")
OBJECT_ID_ERROR("O id fornecido não é um ObjectId válido. Deve ser uma string hexadecimal de 24 caracteres.")
{
"name": "Lasanha",
"category": 1,
"preparationTime": 40,
"preparationMode": "{{$randomLoremParagraph}}",
"ingredients":[
{
"name": " de penne cozido al dente",
"quantity": "500g"
},
{
"name": "dentes de alho picados",
"quantity": "2"
},
{
"name": "de requeijão de sua preferência",
"quantity": "200g"
},
{
"name": " de presunto picado",
"quantity": "300g"
},
{
"name": "Queijo parmesão ralado",
"quantity": "400g"
},
{
"name": "colheres (sopa) de azeite",
"quantity": "2"
},
{
"name": "lata de molho de tomate",
"quantity": "1"
},
{
"name": "lata de creme de leite",
"quantity": "1"
}
]
}
- name: Run UserRoutesKtTest
run: ./gradlew test --tests "br.com.application.routes.UsersRoutesKtTest"
- name: Run RecipesRouteKtTest
run: ./gradlew test --tests "br.com.application.routes.RecipesRoutesKtTest"
- name: Run remaining tests
run: ./gradlew test -x test --tests "br.com.application.routes.UsersRoutesKtTest" --tests "br.com.application.routes.RecipesRoutesKtTest"
- name: Run Unit Tests
run: ./gradlew unitTest
- name: Run UserRoutesKtTest
run: ./gradlew userRoutesKtTest
- name: Run RecipesRouteKtTest
run: ./gradlew recipesRouteKtTest
ws://localhost:8080/api/v1/addConnection/create-qrcode
ws://localhost:8080/api/v1/addConnection/read-qrcode
Caso tenham dificuldades de rodar as tarefas gradlew
usar esse comando:
./gradlew clean test --no-build-cache
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.junit.platform:junit-platform-launcher")
Curso Backend Kotlin com Ktor – API do Receita Fácil
Neste curso, você vai desenvolver do zero a API do aplicativo Receita Fácil, utilizando Ktor, o framework assíncrono e leve da JetBrains, ideal para aplicações Kotlin multiplataforma. O projeto segue os princípios da Clean Architecture, com separação clara de responsabilidades entre camadas (Application, Domain, Infrastructure), além de aplicar boas práticas com injeção de dependência via Koin, manipulação segura de dados e modularização do código.
A persistência dos dados é feita com MongoDB, um banco NoSQL flexível e amplamente utilizado para aplicações modernas. Você aprenderá a modelar dados com classes Kotlin, usar anotações BSON, trabalhar com ObjectId e estruturar repositórios assíncronos de forma eficiente.
Um dos grandes diferenciais do projeto é a implementação de WebSockets para compartilhamento de receitas via QR Code, permitindo comunicação em tempo real entre diferentes usuários. Toda a lógica de sessão, troca de mensagens e tratamento de erros será implementada do zero.
Ao final do curso, faremos o deploy completo na plataforma Render, com configuração de variáveis de ambiente, integração com MongoDB na nuvem e preparação para ambiente de produção.
Stack Tecnológica:
Ktor (Routing, Serialization, StatusPages, WebSockets, CallLogging)
MongoDB com driver oficial assíncrono
Koin para Dependency Injection
JWT para autenticação segura
WebSockets com gerenciamento de sessões
Render para deploy e hosting
Kotlin Coroutines para IO assíncrono
Este curso é ideal para desenvolvedores Kotlin que desejam criar APIs robustas e escaláveis com tecnologias modernas e uma stack enxuta. Também é o backend oficial do app Android Receita Fácil, mas pode ser utilizado como base para qualquer aplicação.