Kotlin Ktor REST Service

Overview

Kotlin Ktor REST Service

Servicio web para API REST con Kotlin y Ktor.

Kotlin LISENCE GitHub

imagen

Acerca de

El proyecto consiste en realizar un servicio REST con Kotlin y Ktor. Para ello vamos a usar la tecnologías que nos propone Jetbrains para hacer todo el trabajo, desde la creación de la API REST, hasta la implementación de la misma, así como la serialización de objetos y/o acceso al almacenamiento de los mismos.

Ktor

Ktor es un nuevo framework para desarrollar servicios y clientes asincrónicos. Es 100% Kotlin y se ejecuta en usando Coroutines. Admite proyectos multiplataforma, lo que significa que puede usarlo para cualquier proyecto dirigido a JVM, Android, iOS o Javascript. En este proyecto aprovecharemos Ktor para crear un servicio web para consumir una API REST. Además, aplicaremos Ktor para devolver páginas web.

ktor

Punto de Entrada

El servidor tiene su entrada y configuración en la clase Application. Esta lee la configuración en base al fichero de configuración y a partir de aquí se crea una instancia de la clase Application en base a la configuración de module().

Creando rutas

Las rutas se definen creando una función de extensión sobre Route. A su vez, usando DSL se definen las rutase en base a las petición HTTP sobre ella. Podemos responder a la petición usando call.respondText(), para texto; call.respondHTML(), para contenido HTML usando Kotlin HTML DSL; o call.respond() para devolver una respuesta en formato JSON o XML. finalmente asignamos esas rutas a la instancia de Application, es decir, dentro del método module(). Un ejemplo de ruta puede ser:

routing {
    // Entrada en la api
    get("/") {
        call.respondText("👋 Hola Kotlin REST Service con Kotlin-Ktor")
    }
}

Serializando a JSON

Para serializar objetos a JSON, usamos la librería de serialización de Kotlin, especialmente para hacer la negociación de contenido en JSON.

Para ello, las clases POJO a serailizar son indicadas con @Serializable.

import kotlinx.serialization.Serializable

@Serializable
data class Customer(var id: String, val firstName: String, val lastName: String, val email: String)

Posteriormente, en nuestra Application de Ktor, instalamos como un plugin la negociación de contenido en JSON.

install(ContentNegotiation) {
  json()
}

Procesando Request

Dentro de un controlador de ruta, puedes obtener acceso a una solicitud utilizando la propiedad call.request. Esto devuelve la instancia de ApplicationRequest y proporciona acceso a varios parámetros de solicitud.

routing {
    get("/") {
        val uri = call.request.uri
        call.respondText("Request uri: $uri")
    }
}

Parámetros de ruta

Para obtener acceso a los valores de los parámetros de ruta mediante la propiedad call.parameters. Por ejemplo, call.parameters["login"] devolverá admin para la ruta /user/admin

get("/user/{login}") {
    if (call.parameters["login"] == "admin") {
        call.respondText("Request admin: ${call.parameters["login"]}")
    }
}

Parámetros de consulta

Para obtener acceso a los parámetros de una cadena de consulta, puede usar la propiedad ApplicationRequest.queryParameters. Por ejemplo, si se realiza una solicitud a /products?price=asc, puede acceder al parámetro de consulta de precio.

get("/products") {
    if (call.request.queryParameters["price"] == "asc") {
        call.respondText("Request price: ${call.request.queryParameters["price"]}")
    }
}

Parámetros de cuerpo

Ktor proporciona un complemento de negociación de contenido para negociar el tipo de medio de la solicitud y deserializar el contenido a un objeto de un tipo requerido. Para recibir y convertir contenido para una solicitud, llama al método de recepción que acepta una clase de datos como parámetro.

() customerStorage.add(customer) call.respondText("Customer stored correctly", status = HttpStatusCode.Created) }">
post("/customer") {
    val customer = call.receive<Customer>()
    customerStorage.add(customer)
    call.respondText("Customer stored correctly", status = HttpStatusCode.Created)
}

Peticiones multiparte

Si necesita recibir un archivo enviado como parte de una solicitud de varias partes, llame a la función receiveMultipart y luego recorra cada parte según sea necesario. En el siguiente ejemplo, PartData.FileItem se usa para recibir un archivo como flujo de bytes.

val fileName = part.originalFileName as String var fileBytes = part.streamProvider().readBytes() File("uploads/$fileName").writeBytes(fileBytes) part.dispose() } call.respondText("$fileName is uploaded to 'uploads/$fileName'") }">
post("/upload") {
    //  multipart data (suspending)
    val multipart = call.receiveMultipart()
    multipart.forEachPart { part ->
      val fileName = part.originalFileName as String
      var fileBytes = part.streamProvider().readBytes()
      File("uploads/$fileName").writeBytes(fileBytes)
      part.dispose()
    }
    call.respondText("$fileName is uploaded to 'uploads/$fileName'")
}

Autenticación y Autorización

Podemos implementar métodos de autenticación y autorización variados con Ktor. Este ejemplo se ha procedido a usar JWT Tokens. Para ello se ha instalado las librerías necesarias para el procesamiento de tokens JWT. Los parámetros para generar el token se han configurado en el fichero de configuración. Debemos tener en cuenta algunos parámetros para proteger y verificar los tokens, así como su tiempo de vida. Posteriormente lo instalamos como un plugin más en la configuración de la aplicación. Podemos configurar su verificador y ademas validar el payload para analizar que el cuerpo del token es válido, tal y como se indica el la documentación de Ktor.

install(Authentication) {
    jwt {
        // Configure jwt authentication
    }
}

Por otro lado, cuando nos logueamos, podemos generar el token y devolverlo al usuario, en base a los parámetros de configuración.

Para proteger ls rutas usamos la función athenticate. Cualquier ruta dentro de ella quedará protegida por la autenticación. Además si leemos en el Payload el usuario y administramos alguna política de permisos, podemos verificar que el usuario tiene permisos para acceder a la ruta.

() val username = principal!!.payload.getClaim("username").asString() val expiresAt = principal.expiresAt?.time?.minus(System.currentTimeMillis()) call.respondText("Hello, $username! Token is expired at $expiresAt ms.") } } }">
routing {
    authenticate("auth-jwt") {
        get("/hello") {
            val principal = call.principal<JWTPrincipal>()
            val username = principal!!.payload.getClaim("username").asString()
            val expiresAt = principal.expiresAt?.time?.minus(System.currentTimeMillis())
            call.respondText("Hello, $username! Token is expired at $expiresAt ms.")
        }
    }
}

Referencia API REST

Recurso Customers

Get all customers

  GET /rest/customers?limit={limit}

Get customer by id

  GET /rest/customers/{id}

Update customer by id

  PUT /rest/customers/{id}

Delete customer by id

  DELETE /rest/customers/{id}

Recurso Orders

Get all orders

  GET /rest/orders?limit={limit}

Get order by id

  GET /rest/orders/{id}

Update order by id

  PUT /rest/orders/{id}

Delete order by id

  DELETE /rest/orders/{id}

Get contents by order id

  GET /rest/orders/{id}

Get contents by order id

  GET /rest/orders/{id}/contents

Get total by order id

  GET /rest/orders/{id}/total

Get customer by order id

  GET /rest/orders/{id}/customer

Subida/Bajada de archivos

Get/Download file by name

  GET /rest/uploads/{fileName}

Post/Upload file

  POST /rest/uploads/

Delete file

  DELETE /rest/uploads/{fileName}

Recursos Autenticados

Login user.

  
  POST /rest/auth/login

Register

  POST /rest/auth/register

Me

  
  GET /rest/auth/me

Get all Users

  
  GET /rest/auth/users

PostMan

Puedes consumir el servicio REST con PostMan. Para ello solo debes importar la colección de ejemplo y ejecutar las mismas.

Autor

Codificado con 💖 por José Luis González Sánchez

Twitter GitHub

Contacto

Cualquier cosa que necesites házmelo saber por si puedo ayudarte 💬 .

        

Licencia

Este proyecto está licenciado bajo licencia MIT, si desea saber más, visite el fichero LICENSE para su uso docente y educativo.

You might also like...
Kotlin microservices with REST, and gRPC using BFF pattern. This repository contains backend services. Everything is dockerized and ready to
Kotlin microservices with REST, and gRPC using BFF pattern. This repository contains backend services. Everything is dockerized and ready to "Go" actually "Kotlin" :-)

Microservices Kotlin gRPC Deployed in EC2, Check it out! This repo contains microservices written in Kotlin with BFF pattern for performing CRUD opera

Spring-kotlin - Learning API Rest with Kotlin, Spring and PostgreSQL

Kotlin, Spring, PostgreSQL and Liquibase Database Migrations Learning Kotlin for

API Rest With Kotlin And Spring Boot

##API REST WITH KOTLIN AND SPRING BOOT GET Url: http://localhost:8080/customers Response (Status Code: 200 Ok) { "_embedded": { "customer

Katoot - An easy-to-use (blocking) Kotlin wrapper for Kahoot's REST api

katoot An easy-to-use (blocking) Kotlin wrapper for Kahoot's REST api. Usage Qui

Ejemplo de API Rest Blog con Spring Boot + Kotlin + Gradle
Ejemplo de API Rest Blog con Spring Boot + Kotlin + Gradle

Blog Ejemplo de API Rest Blog con Spring Boot 2.7.3 + Kotlin + Gradle + Java 17 El objetivo es que pueda servir como guía para el aprendizaje, lo más

Este es un ejemplo de como usar Kotlin en un proyecto Node.js, una api rest en Node.js con Express
Este es un ejemplo de como usar Kotlin en un proyecto Node.js, una api rest en Node.js con Express

Kotlin Hello Node.js Este es un ejemplo de como usar Kotlin en un proyecto Node.js, una API REST con Express Kotlin Hello Node.js Acerca de Uso Compil

Ejemplo de App Android con Kotlin, Jetpack Compose, Retrofit y consumo de la API REST de Pokémon
Ejemplo de App Android con Kotlin, Jetpack Compose, Retrofit y consumo de la API REST de Pokémon

Pokémon Jetpack Compose Ejemplo de App Android con Kotlin, Jetpack Compose, Retrofit y consumo de la API REST de Pokémon Jetpack Compose Retrofit Poké

Kotlin backend based on the Clean Architecture principles. Ktor, JWT, Exposed, Flyway, KGraphQL/GraphQL generated endpoints, Gradle.
Kotlin backend based on the Clean Architecture principles. Ktor, JWT, Exposed, Flyway, KGraphQL/GraphQL generated endpoints, Gradle.

Kotlin Clean Architecture Backend Kotlin backend based on the Clean Architecture principles. The application is separated into three modules: Domain,

SSU u-saint parser with Kotlin-Multiplatform and Ktor.

kusaint Soongsil University(SSU) u-Saint Parser with Kotlin Multiplatform. Prerequisites JVM !!IMPORTANT!! To run kusaint as a library in JVM environm

Owner
José Luis González Sánchez
Dr. en Informática (PhD). Profe de Secundaria en DAM/DAW/ASIR. Soy GitHub Campus Advisor y Embajador de GitKraken. Tenis, rock, guitarra y buenos momentos.
José Luis González Sánchez
Api Rest Card Game made in Kotlin with Ktor

ApiRest-CardGame "Card Game API" is a project made in Kotlin with Ktor. The API allows you to manage a simple card game deck (shuffle, take a card, pu

null 0 Dec 4, 2021
Demo Spting REST Service on Kotlin. Works with PostgreSQL via Spring Data. Data initialization provided by liquibase

Spring Boot REST API with Kotlin Spring Boot REST API service. Spring Data with PostgreSQL. Data initialization with Liquibase. Swagger UI Reference D

null 0 Jun 10, 2022
intera.kt is a Kotlin library for interacting with the Discord Interactions API through a gateway service or a REST API.

?? Overview ⚠️ WARNING: intera.kt is a work in progress. It is not yet ready for use. You may encounter bugs and other issues, but please report if yo

Pedro Henrique 1 Nov 30, 2021
intera.kt is a Kotlin library for interacting with the Discord Interactions API through a gateway service or a REST API.

?? Overview ⚠️ WARNING: intera.kt is a work in progress. It is not yet ready for use. You may encounter bugs and other issues, but please report if yo

Pedro Henrique 1 Nov 30, 2021
Cargo service: REST API, Spring Boot, Kotlin, JDBC, PostgreSQL

cargo-jdbc Cargo service, training project with Spring Boot, JDBC and Kotlin. To

Valeriy Emelyanov 1 Dec 7, 2022
Kotlin SpringBoot REST Service

Kotlin SpringBoot REST Service Servicio web para API REST con Kotlin y SpringBoot. Kotlin SpringBoot REST Service Acerca de Autor Contacto Licencia Ac

José Luis González Sánchez 2 Mar 10, 2022
KTor-Client---Android - The essence of KTor Client for network calls

KTor Client - Android This project encompasses the essence of KTor Client for ne

Mansoor Nisar 2 Jan 18, 2022
Aagent-new-service-parent - A Springboot Rest Webservice Project that can be deployed to a Docker container

Webservice in a Docker Container A Springboot Rest Webservice Project that can b

ReeceRiley-aa 0 Jan 4, 2022
Team management service is a production ready and fully tested service that can be used as a template for a microservices development.

team-mgmt-service Description Team management service is a production ready and fully tested service that can be used as a template for a microservice

Albert Llousas Ortiz 18 Oct 10, 2022
Accessibility-Service - Filter url from browser by using accessibility service

Accessibility Service example Filter url from browser by using accessibility ser

AmirMohammad Yazdanmanesh 8 Nov 29, 2022