komparing kotlin server frameworks
play

Komparing Kotlin Server Frameworks Ken Yee @KAYAK (Android and - PowerPoint PPT Presentation

Komparing Kotlin Server Frameworks Ken Yee @KAYAK (Android and occasional backend developer) KotlinConf 2018 Agenda - What is a backend? - What to look for in a server framework? - What Kotlin frameworks are available? - Pros/Cons of each


  1. Komparing Kotlin Server Frameworks Ken Yee @KAYAK (Android and occasional backend developer) KotlinConf 2018

  2. Agenda - What is a backend? - What to look for in a server framework? - What Kotlin frameworks are available? - Pros/Cons of each framework - Avoiding framework dependencies - Serverless

  3. What is a Backend? REST API Web server Chat server

  4. 1. Backends are What apps/clients talk to so that users can Read dynamic data ➔ So you can share information Authenticate ➔ Because it’s about user access Write persistent data ➔ To save user interactions

  5. 2. Backends must Be reliable Read dynamic data ➔ Scalable from user load Authenticate ➔ Secure from hacking Write persistent data ➔ Resilient to server failures

  6. What do you look for in a framework? Kotlin, DSL, Websockets, HTTP/2, Non-Blocking, CORS, CSRF, OIDC, OAuth2, Testing, Documentation

  7. 1. Kotlin! On the server is: Isomorphic Language ➔ With Kotlin clients Concise and Modern ➔ Extension and Higher Order functions, DSLs, Coroutines Null/Type Safe ➔ Versus Javascript, Python, Ruby Compatible w/ Java8 ➔ Delay moving to Java 9/10/11

  8. Java ( Spring ) Kotlin (Spring) class BlogRouter(private val blogHandler: public class BlogRouter { BlogHandler) { public RouterFunction<ServerResponse> fun router() = route(BlogHandler blogHandler) { return RouterFunctions router { .route(RequestPredicates.GET("/blog").and(RequestPredicat ("/blog" and accept(TEXT_HTML)).nest { es.accept(MediaType.TEXT_HTML)), GET("/", blogHandler::findAllBlogs) blogHandler::findAllBlogs) GET("/{slug}", .route(RequestPredicates.GET("/blog/{slug}").and(RequestPr blogHandler::findOneBlog) edicates.accept(MediaType.TEXT_HTML)), blogHandler::findOneBlog) } .route(RequestPredicates.GET("/api/blog").and(RequestPredi ("/api/blog" and cates.accept(MediaType.APPLICATION_JSON)),blogHandle r::findOne) accept(APPLICATION_JSON)).nest { GET("/", blogHandler::findAll) .route(RequestPredicates.GET("/api/blog/{id}").and(Request GET("/{id}", blogHandler::findOne) Predicates.accept(MediaType.APPLICATION_JSON)), blogHandler::findOne); } } } } }

  9. Express.js Kotlin (Spring) var router = express.Router() class BlogRouter(private val blogHandler: var blogHandler = BlogHandler() BlogHandler) { fun router() = router.get('/blog', function (req, res) { router { res.send(blogHandler.findAllBlogs()) ("/blog" and accept(TEXT_HTML)).nest { }) GET("/", blogHandler::findAllBlogs) router.get('/blog/:slug', function (req, res) { GET("/{slug}", res.send(blogHandler.findOneBlog(req)) blogHandler::findOneBlog) }) } router.get('/api/blog', function (req, res) { ("/api/blog" and res.send(blogHandler.findAll()) accept(APPLICATION_JSON)).nest { }) GET("/", blogHandler::findAll) router.get('/blog/:id', function (req, res) { GET("/{id}", blogHandler::findOne) res.send(blogHandler.findOne(req)) } }) } }

  10. 2. Speed Efficiency Non-blocking ➔ Reactor/RxJava/Kotlin Coroutines Event driven w/ Netty vs. threading Http/2 ➔ Formerly Google’s SPDY that uses single connections for multiple downloads Push resources to clients Websockets ➔ Useful for real-time chat/games

  11. 3. CORS (web) Cross Origin Resource Sharing Browser security ➔ Allows browsers to access different domains for static files (images, CSS, JS, HTML, etc.) Javascript security ➔ Allows web clients to use different hosts for APIs

  12. 4. CSRF (web) Cross Site Request Forgery Browser form security ➔ Prevents other sites from sending in the same form fields for a request Javascript API call security ➔ Prevent AJAX calls from being run from malicious sites

  13. 5. OAuth2/OIDC Delegation vs. Authentication Oauth2 ➔ Standard refresh tokens and access token that can be revoked Only for delegation OIDC ➔ OpenID Connect; aka, OAuth2 v2 or OpenID v3 User verification JSON Web Token encoded data Auth token and delegation token Keycloak, Hydra, Okta, Auth0

  14. 6. Testing Bug prevention Unit Testing ➔ Test internal business logic Integration Testing ➔ Test server integration

  15. 7. Documentation How, Help Official Documentation ➔ Clear documentation for features Useful examples Community ➔ StackOverflow Github stars Real projects API ➔ Swagger/RAML

  16. Which frameworks? Ktor, Http4K Jooby Vert.x Spring, ...

  17. Frameworks Spring Ratpack SparkJava Age Vert.x Jooby Ktor Http4K Javalin Micronaut Features

  18. Ktor Ktor Routing Pros routing { ➔ accept(ContentType.Text.Html) { JetBrains’ official server framework get(“/blog”) { Pure Kotlin call.respond(blogHandler::findAllBlogs) } Goal of Kotlin/Native support get(“/blog/{slug}”) { Kotlin coroutine support call.respond(blogHandler::findOneBlog) Websockets } } Uses Netty for async engine Includes Multi-platform client accept(ContentType.Application.Json) { Oauth support for Google/Twitter/FB get("/api/blog") { call.respond(blogHandler::findAll) Cons ➔ } get("/api/blog/{id}") { Least mature pure-Kotlin framework call.respond(blogHandler::findOne) Not much module support but enough } Only Freemarker/Velocity templates } } No opentracing/micrometer support

  19. Ktor Coroutines get("/{...}") { withContext(CommonPool) { call.slow() } } private suspend fun ApplicationCall.slow() { respondHtml { body { "Slow result" } } }

  20. Monolith Architecture Web Load Clients Balancers DB API

  21. Microservice Architecture Gateway Web Account Load Clients Balancers/ Service Cart Locators Logging (ELK) Tracing (Zipkin)

  22. Service Mesh Massively Distributed ➔ Self-Healing ➔ Self-Scaling ➔ Debugging is hard ➔ Logging is hard ➔ Perf monitoring is hard ➔ Paradigma Digital

  23. Http4K Http4K Routing Pros routes( ➔ “/blog” bind routes( Pure Kotlin “/” bind GET to { _ -> bloghandler.findAllBlogs() No magic reflection/annotations }, Resilience4J support “/{slug}” bind GET to { req -> bloghandler.findOneBlog(req) } Pluggable backends (Netty/Undertow) ), Micrometer support “/api” bind routes( Swagger support “/blog” bind GET to { _ -> bloghandler.findAll() OAuth support for Auth0 and Google }, “/blog/{id}” bind GET to { req -> Can deploy to AWS Lambda bloghandler.findOne(req) } GraalVM support ) Chaos testing ).asServer(Jetty(8000)).start() Cons ➔ No Kotlin coroutine support No Opentracing but has Zipkin No auto JSON encode/decode

  24. Jooby Jooby Routing Pros class App: Kooby({ ➔ use(Jackson()) Pluggable backends Event loop non-blocking get("/blog") { RxJava/Reactor bloghandler.findAllBlogs() } Even more modules than Http4K get("/blog/:slug") { req -> Swagger/RAML Lots of DB support bloghandler.findOneBlog(req.param(“slug”).value) Job scheduling } Cons ➔ get("/api/blog") { bloghandler.findAll() No Kotlin coroutine support } No zipkin or opentracing support get(“/api/blog/:id”) { blogHandler.findOne(req.param<Int>(“id”)) } })

  25. Vert.x Vert.x Routing Pros private val router = ➔ Kotlin coroutine support Router.router(vertx).apply { Event loop non-blocking get("/blog") Near top in TechEmpower .handler(bloghandler::findAllBlogs) benchmarks get("/blog/:slug") Micrometer and Hawkular .handler(bloghandler::findOneBlog) Auto-clustering Polyglot (JS, Python, Clojure, Java, etc.) get("/api/blog") Redpipe for RxJava .handler(bloghandler::findAll) Kovert (convention vs. configuration) get("/api/blog/:id") Swagger support .handler (bloghandler::findOne) GraalVM support coming soon } Cons ➔ A bit more monolith than microservice Not very mainstream in US No auto JSON encode/decode

  26. Vert.x

  27. Vert.x Kovert route.bindController(BlogApiController, “/api”) class BlogApiController(val blogHandler: BlogHandler = Injekt.get()) { public fun listBlog(): List<Blog> = blogHandler.findAll() public fun findBlogById(val id: String): Blog = { val blog = blogHandler.findOne(id) if (blog == null) throw HttpErrorNotFound() return blog } Autogens: /api/blog - list of blogs /api/blog/:id - get blog with id

  28. Spring Spring Routing Pros class BlogRouter(private val blogHandler: ➔ BlogHandler) { Most popular framework fun router() = Webflux/Reactor non-blocking router { Kitchen sink can be daunting ("/blog" and accept(TEXT_HTML)).nest { Spring Initializer project autogen GET("/", blogHandler::findAllBlogs) JHipster GET("/{slug}", Swagger support blogHandler::findOneBlog) GraalVM support in 5.2 } Cons ➔ ("/api/blog" and Need kotlin-spring/jpa plugins accept(APPLICATION_JSON)).nest { No official Kotlin coroutine support GET("/", blogHandler::findAll) (see Kaminski’s coroutine library - GET("/{id}", blogHandler::findOne) Spring Fu) } Slowest framework } }

  29. Spring WebFlux @GetMapping("/api/blog/{id}") public Mono<ResponseEntity<Blog>> getBlogById(@PathVariable(value = "id") String blogId) { return Mono.fromCallable(blogHandler.findOne(blogId)) .map(blog -> ResponseEntity.ok(blog)) .defaultIfEmpty(ResponseEntity.notFound().build()); }

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend