Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin for backend development

Kotlin for backend development

In this talk, we discover the framework Ktor and how to build safe and scalable backend by using Coroutines, FreeMaker, Routing, Authentication etc........

Segnonna Hospice HOUNSOU

September 14, 2019
Tweet

More Decks by Segnonna Hospice HOUNSOU

Other Decks in Technology

Transcript

  1. G o o g l e D e v e

    l o p e r G r o u p D a k a r Kotlin for backend development 1
  2. I am here because I am Android developer and I

    use Kotlin on a daily basis. Hello! I am Hospice Hounsou Github: @hounsouh Twitter: @hoshouns 2
  3. WHAT IS KOTLIN? Very easy to learn Language developed by

    JetBrains Very intuitive Learning Kotlin become the language of reference in many platforms, and sharing code among all them is undoubtedly a high selling point Total integration with IDEs More expressive More safe High interoperability Sponsored by Google 4
  4. Expressiveness • Much easier to avoid boilerplate • The language

    covers the most commons pattern by default 5
  5. 6 public class SignUpPayload { private String mFirstName; private String

    mLastName; private String mUserName; public SignUpPayload(String userName, String firstName, String lastName){ mUserName =userName; mFirstName =firstName; mLastName =lastName; } public String getmFirstName() { return mFirstName; } public void setmFirstName(String mFirstName) { this.mFirstName = mFirstName; } public String getmLastName() { return mLastName; } public void setmLastName(String mLastName) { this.mLastName = mLastName; } public String getmUserName() { return mUserName; } public void setmUserName(String mUserName) { this.mUserName = mUserName; } @Override public String toString() { return super.toString(); } @Override public boolean equals(Object obj) { return super.equals(obj); } } data class SignUpPayload(val username: String, val firstname: String, val lastname: String)
  6. 8 //This does not compile. SignUpPayload can not be null

    val notNullSignUpPayload: SignUpPayload = null //SignUpPayload can be null val signUpPayload: SignUpPayload? = null val userName=null SignUpPayload(userName?:"","FirstName","LastName")
  7. Nested functions 9 fun userCanMakeTransaction(): Boolean { fun userStatus(): Boolean

    { return false } fun subscriptionState():Boolean{ return false } return userStatus().and(subscriptionState()) }
  8. High-orders functions 11 fun <T> justTry(block: () -> T) =

    try {block() }catch (e: Throwable) {} justTry{ fetchData() }
  9. Idiomatic API Build by JetBrains Easy to use Use Coroutines

    for high scalability KTOR? 16 Fun and asynchronous
  10. 18

  11. 01 02 03 Save user in a database List, update

    and delete registered users via a simple dashboard Create an endpoint to register a user Main goals 20
  12. interface UserRepoInterface { suspend fun create(user: User): User? suspend fun

    read(userName: String): User? suspend fun update(userId: String, user: User): Boolean suspend fun delete(userId: Int): Boolean suspend fun getAll(): Customers } 23
  13. fun Route.user(userRepo: UserRepoInterface) { route("/user-api/") { post(“signup”){ val signupPayload =

    call.receive<SignUpPayload>() userRepo.read(signupPayload.username)?.let { call.respond(HttpStatusCode.Created, message = SignupResponse(token = it.token)) } } } } 25
  14. fun Route.user(userRepo: UserRepoInterface) { route("/user-api/") { post(“signup”){ val signupPayload =

    call.receive<SignUpPayload>() userRepo.read(signupPayload.username)?.let {} ?: run { val user = userRepo.create( User(userName = signupPayload.username, firstName = signupPayload.firstname, lastName = signupPayload.lastname, token = RandomString.make(50))) call.respond(HttpStatusCode.Created, message = SignupResponse(token = user?.token ?: RandomString.make(50))) } } } } 26
  15. fun Route.user(userRepo: UserRepoInterface) { route("/user-api/") { post(“signup”){} get("customers") { try

    { call.respond(FreeMarkerContent("users.ftl", mapOf("customers" to userRepo.getAll()))) } catch (e: Exception) { call.respond(HttpStatusCode.BadRequest) } } } } 27
  16. 28 <#-- @ftlvariable name="customers" type="hos.houns.model.Customers" --> <#list customers.list as customer>

    <tr> <th scope="row">${customer.userId}</th> <td>${customer.firstName}</td> <td>${customer.lastName}</td> <td> <form method="post" action="customers"> <input type="hidden" name="userId" value=“$ {customer.userId}”/> <input type="hidden" name="action" value="delete"/> <button type="submit" title="Delete">Delete</button> </form> </td> </tr> </#list>
  17. fun Route.user(userRepo: UserRepoInterface) { route("/user-api/") { post(“signup”){} authenticate("adminAuth") { get("customers")

    {} post("customers") { val userId = parameters["userId"] ?: throw IllegalArgumentException("missing parameter: id") val action = parameters["action"] ?: throw IllegalArgumentException("missing parameter: action") } }}} 30
  18. fun Route.user(userRepo: UserRepoInterface) { route("/user-api/") { post(“signup”){} authenticate("adminAuth") { get("customers")

    {} post("customers") { when (action) { "delete" -> userRepo.delete(userId.toInt()) "disable" -> { //TODO } } call.respondRedirect("/user-api/customers") } }}} 31