0% found this document useful (0 votes)
62 views

Kotlin Spring

Uploaded by

savibok424
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
62 views

Kotlin Spring

Uploaded by

savibok424
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 88

Building Restful Services

Using
Spring Boot and Kotlin

Dilip
About Me

• Dilip

• Building Software’s since 2008

• Teaching in UDEMY Since 2016


Why this course on Kotlin ?
What’s Covered ?
• Kotlin Introduction

• Code and Explore Kotlin Fundamentals

• Kotlin and SpringBoot Integration

• Build a RestFul Service using Kotlin and SpringBoot

• Unit/Integration tests using JUnit5 and Kotlin


Targeted Audience
• Experienced Java Developers

• Any Java Developer who is interested in learning Kotlin can enroll in this
course

• Any Java/Kotlin Developer who is interested in building applications using


SpringBoot can enroll in this course
Source Code
Thank You!
Prerequisites
• Java 17 (Java 11 or Higher is needed)

• Prior Java Experience is a must

• Prior Spring Framework Experience is a must

• Experience Writing JUnit tests

• Intellij or any other IDE


Kotlin Introduction
What is Kotlin?
• Kotlin is a modern object oriented and functional programming language

• Kotlin is a statically typed Programming language like Java

• All the types are resolved at compile time

• This is free and open source language licensed under Apache 2.0
Who uses Kotlin ?
Why Kotlin ?
• Kotlin is an expressive language and it has a concise syntax

• Code readability and maintainability

• Kotlin is a safe language which prevents un-necessary errors

• Prevents NullPointerException using the Nullable and Non-Nullable types

• Interoperable with Java

• Kotlin and Java works together very well


What kind of applications can we build with Kotlin ?
• Build Server Side Applications

• Web Applications

• RestFul Services

• Messaging Applications

• Build any kind of applications that we can build using Java

• Widely used in the Android


Popular Framework Support
Kotlin Community
How does Kotlin work with the
JVM ?
Kotlin Build Process

Kotlin
*.kt *.class .jar
Compiler
Java Runtime
Environment
Kotlin/Java Build Process

Kotlin
*.kt *.class .jar
Compiler

Java Runtime
Java
*.java *.class .jar Environment
Compiler
val & var
• Any variable in Kotlin should be declared as val or var
• val
• Variables declared with val are immutable variables
val name : String = "Dilip"

Name of the Type of the


Variable Variable

• var
• Variables declared with var are mutable variables
var age : Int = 33

Name of the Type of the


Variable Variable
Types in Kotlin
• In Kotlin, there is no distinction between primitives and wrapper types
• All numbers in Kotlin are represented as types
• Integer Types - Byte, Short, Int, Long
• Floating-Point Types - Float, Double
• Character Type - Char
• Boolean Type - Boolean
String and its related Operations
• String Interpolation
val course = "Kotlin Spring"
println("course : $course and the length of the course is ${course.length}")

• Multiline Strings using TripleQuotes


val multiLine1 ="""
ABC
DEF
""".trimIndent()
if-else
• if-else is an expression in kotlin
• Expression always evaluate to a result
val result = if(name.length == 4){
println("Name is Four Characters")
name
}else{
println("Name is Not Four Characters")
name
}
when
• when block allows us to write concise and expressive code when dealing with
multiple conditions

val medal1 = when(position){


1 -> "GOLD"
2 -> "SILVER"
3 -> {
println("Inside position 3")
"BRONZE"
}
else -> "NO MEDAL"
}
Ranges

val range = 1..10 Creates a Range of 10 values


for (i in range){
println(i)
}

val reverseRange = 10 downTo 1 Progression of Values in decreasing order


for (i in reverseRange){
println(i)
}
for (i in reverseRange step 2){ Skip values in the iteration
println(i)
}
while doWhile

fun exploreWhile() { fun exploreDoWhile() {


var x = 1 var i = 0
while(x < 5){ do {
println("Value of x is $x") println("Inside do while : $i")
x++ i++
} }while (i < 5)
} }
break label return
fun label() {
for(i in 1..5){ loop@ for(i in 1..5){ listOf(1,2,3,4,5).forEach each@{
println("i in label $i: ") //if(it==3) return@forEach
println("i is $i ") innerLoop@ for (j in 1..10){ if(it==3) return@each
if(i==3) break //if(j==2) break@innerLoop }
} if(j==2) break@loop
}
}
}
Functions in Kotlin
Function
• Functions are primarily used in Object Oriented Language to express some
behavior or logic
Function Name

fun printHello(){

println(“Hello!") ] Function Body

}
Functions with No return value
• Functions wit no return value are represented as Unit in Kotlin

fun printHello() : Unit {


println("Hello!")
}

• De ning Unit is redundant and it can be ignored


fi
Function with parameters and return value
• Functions with expression body can
be simpli ed like below

fun addition(x: Int, y : Int) : Int { fun addition(x: Int, y : Int) = x+y

return x+y

}
fi
Default Value Parameters
&
Named Arguments
Default Value Parameters
• This provides a default value to a function parameter when its not passed by
the caller

fun printPersonDetails(name : String, email : String = "",


dob : LocalDate = LocalDate.now()){

println("Name is $name and the email is $email and the dob is $dob")
}
Named Arguments
• The caller can invoke the function by using the variable name
fun printPersonDetails(name : String, email : String = "",
dob : LocalDate = LocalDate.now()){

println("Name is $name and the email is $email and the dob is $dob")
}

• Caller can invoke the function using the name of the function arguments, in no particular order
printPersonDetails(dob = LocalDate.parse("2000-01-01") , name = "Dilip", email =
"[email protected]")
Top Level
Functions & Properties
Top Level Functions
• Functions that does not belong to a class are top-level functions

• In Java , functions can only be part of class

• In Java applications, you can nd classes that just has some static methods
which holds some common logic that can be used across the app

• Kotlin avoids this by using top level functions that can be part of a Kotlin le
not a class
fi
fi
Top Level Properties
• In Kotlin, properties that does not belong to class are called top-level
properties

• In Java, you can only de ne properties in a class or an interface

• Most common use case in a Java application is you may have to be de ne


static constants in a class le that can be used across the app

• Kotlin avoids these by allowing us to create properties that can be part of a


Kotlin le not a class
fi
fi
fi
fi
Class
Class in Object Oriented Programming
• Class in object oriented programming is fundamentally the blueprint for
creating objects
class Person {
fun action(){
println("Person Walks")
}
}

Instance of the class:


val person = Person() // new keyword is not needed

person.action()
Constructors in Kotlin
Constructors in Kotlin
• Constructors is a concept in object oriented programming through which we
can create an Object with initial values
1
class Person(val name: String,
val age: Int) { Primary Constructor
2
fun action() {
println("Person Walks")
}
}

Instance of the class:

val person = Person("Alex", 25)


Secondary Constructor
• This is an alternative way of de ning constructors

class Item(){
var name : String = ""
constructor(_name : String) : this(){
name = _name
}
}

• constructor keyword
• this() call to the actual class is
mandatory
fi
Recommended approach for constructors
• Use Primary Constructors whenever possible

• Use default values for overloaded constructor scenario

class Person(val name: String = "",


val age: Int = 0) {

fun action() {
println("Person Walks")
}

}
Use Secondary Constructors only necessary
Initializer code using init block
• init code block can be used to run some initialization logic during the instance
creation

init {

println("Inside Init Block")

}
data class
• Classes just holds the data can be categorized as data classes
• DTOs, domain classes and value object classes fall under this category
• In Java, these type of classes are also Java Beans
data class Course(
val id: Int,
val name: String,
val author: String
)

• Automatically generates the equals(), hashCode() and toString()


methods
Usage & Benefits of data class
• Data classes are primarily for classes that’s going to behave as a data
container

• It autogenerates a lot of functionalities for you when you add the data
modi er to the class

• Its pretty easy to create a clone of the object using the copy( ) function
fi
When to use Custom Getter/Setter ?

Use it when you have the need to


implement the custom logic for setting or
retrieving the properties.
Inheritance
• Inheritance is supported in Kotlin

• Kotlin Concepts:

• Any is the superclass for any class in Kotlin

• Object Class in Java

• All the classes in Kotlin are nal

• Extending classes are not allowed by default


fi
Inheritance - Extending Classes
• Kotlin allows inheritance when open modi er is used

open class User(val name: String) {

open fun login() {


println("Inside user login")
}
}

• Subclass extending the User Class

class Student(name: String) : User(name)

fi
Inheritance - Overriding Functions
• Mark the function with open modi er
open class User(val name: String) {

open fun login() {

println("Inside user login”)

}
}
class Student(name: String): User(name, age) {

override fun login() {

super.login()

println("Inside Student login")


}
}
fi
Inheritance - Overriding Variables
• Similar to functions using the open and override keywords

open class User(val name: String) {

open val isLoggedIn : Boolean = true

class Student(name: String) : User(name, age) {

override val isLoggedIn : Boolean = true

}
object keyword
• This keyword allows us to create a class and an instance of the class at the
same time

• Equivalent to a singleton pattern in java


object Authenticate {

fun authenticate(userName : String, password: String){

println("User Authenticated for userName : $userName”)

} • Limitations

Usage: • You cannot inject constructor arguments to object


classes
fun main() {

Authenticate.authenticate("Dilip", "abc")
}
companion object
• Kotlin does not have the support for the static keyword
• companion object can be used to introduce static functionalities that are tied
to the class.

• Using object inside the class requires you class Student(

to use the companion keyword name: String,


override val age: Int = 0
) : User(name, age) {

• You can have variables and functions companion object {


const val noOfEnrolledCourses = 10
• Usage fun country(): String {
Student.country() return "USA"
}
}

}
Interface
• Interfaces in oops de nes the contract which has some abstract methods

• The classes that implements the interface needs to implement it.

• This is similar to Java

• Interfaces can have abstract and non-abstract methods in it

• It cannot contain any state


fi
Interface
• Interface with abstract method • Interface with abstract/non-abstract
method
interface CourseRepository {
interface CourseRepository { fun getById(id: Int): Course

fun getById(id: Int): Course fun save(course: Course): Int {


println("course : $course")
} return course.id
}
}

class SqlCourseRepository : CourseRepository {


class SqlCourseRepository : CourseRepository {
override fun getById(id: Int): Course {
override fun getById(id: Int): Course { return Course(id = id,
return Course(id = id, "Kafka For Developers using Spring Boot",
"Kafka For Developers using Spring Boot", "Dilip Sundarraj")
"Dilip Sundarraj") }
}
override fun save(course: Course): Int {
} println("course in SqlCourseRepository : $course")
return course.id
}

}
Visibility Modifiers
in
Kotlin
Visibility Modifiers in Kotlin
• There are four visibility modi ers in Kotlin :
• public, protected, private and internal
• public
• This is the default access modi ers
• private
• This marks the function or variable accessible only to that class
• protected
• A protected member is visible in the class and subclass
• internal
• This is new in Kotlin. Anything that’s marked with internal is private to the module that’s
published using the Gradle or Maven
fi
fi
Type Checking & Casting
• Kotlin has some handy operators
• is operator
• Check a particular value is of a certain type
val name = “Dilip"

val result = name is String true or false


• as operator
• Cast a value to a certain type
val name = "Dilip" as String

• If cast is not possible then it throws java.lang.ClassCastException


Nulls in Kotlin
Handling Nulls in Kotlin
• Kotlin handles nulls little di erently compared to Java

• Kotlin has the concept of Nullable and Non-Nullable types

• These can be assigned to variables or properties


ff
Nullable Type Non Nullable Type
• A variable or property can hold a • A variable or property can hold
null value only a non-null value

• How to de ne a Nullable Type? • How to de ne a Non-Nullable


Type?

val nameNullale : String? = null val nameNonNull : String = "Dilip"

Or
null value is not allowed
Or

val nameNullale : String? = “Dilip” val nameNonNull = "Dilip"

By Default , types are Non-Nullable


fi
fi
Dealing with Nulls
Safe Call Operator Elvis Operator Not Null Assertions

• Use the safe call • Return a Default • Making sure the value
operator to invoke value if null is not null after some
functions safely on it updates
val movie =
val length = nameNullable?.length val length = nameNullable?.length ?: 0 saveMovie(Movie(null,
“Avengers”))

println(movie.id!!)
Collections in Kotlin
Collections
• Kotlin re-uses the collections from Java

• Kotlin does not have collections of their own

• Kotlin added a lot of new features through extension functions

• Kotlin has two types of collections

• Mutable Collections

• Immutable Collections
Immutable Collection Mutable Collection
• Collection is not modi able once • Modifying the data in the collection
created is allowed
val names = listOf("Alex", "Ben", “Chloe") val namesMutableList = mutableListOf(“Alex",“Ben", "Chloe")

Map
mapOf("dilip" to 33 ,"scooby" to 4) mutableMapOf("dilip" to 33 ,"scooby" to 4)

Set
setOf("adam", "ben", "chloe") mutableSetOf("adam", "ben", "chloe")
fi
What is a Lambda Expression ?
• Lambda Expressions are small piece of code that can be passed to other
functions

{x: Int -> x * x }


Lamda Body
Lamda Input Argument
Benefit of Lambda Expression
• You can assign the behavior to a variable
val add = { x : Int -> x+x } fun add(x:Int) = x+x

• The advantage here is that , you can pass the lambda as an argument to
other functions
listOf(1, 2, 3)
.forEach {
val result = add(it)
println(result)
}
2 4 6
Collections & Operations on it
• Using Collections are very common in any application development

• Performing some logic on each elements in the list

• Filter out some elements in the collection

• Collections has operators to perform operations on it


filter
• lter
• This is used to lter out the elements from the collection

val numList = listOf(1, 2, 3, 4, 5, 6)

val result = numList.filter {


it >= 5
}
fi
fi
map
• This operator is fundamentally used to transfer the elements from one form to
other form

val numList = listOf(1, 2, 3, 4, 5, 6)

val result = numList.map {


it.toDouble()
}

result : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]


flatMap
• This operators can be used if the collection has another collection
• Used to atten the list of lists that is operating on and returns the result as a
single list
map atMap

val list = listOf(listOf(1,2,3),listOf(4,5,6) ) val list = listOf(listOf(1,2,3),listOf(4,5,6) )

val result = list.map { outerList -> val result = list.flatMap { outerList ->
outerList.map {
outerList.map {
it.toDouble() it.toDouble()
}
}
} }
println("result : $result")
println("result : $result")

result : [ [1.0, 2.0, 3.0], [4.0, 5.0, 6.0] ] result : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
fl
fl
Lazy Evaluation of Collections using Sequences
• This is an alternative API to work with collections
• The operations on the elements of the collection are evaluated lazily
Not a sequence sequence

val namesListUsingSequence = listOf("alex", "ben", “chloe")


val namesList = listOf("alex", "ben", “chloe")
.asSequence()
.filter { it.length >= 4 } // [“alex","chloe"]
.filter { it.length >= 4 } // “alex" “ben” “chloe"
.map { it.uppercase() } // ["ALEX","CHLOE"]
.map { it.uppercase() } // “ALEX" “CHLOE"

.toList() “ALEX" “CHLOE"

Terminal Operator
Whats the benefit of using Sequences ?

• Sequences perform better when dealing with collections that are extremely
big

• Does not create intermediate collection for each operator


• Sequences are lazy, does not apply the operations for all the elements in
the collection
Arrays in Kotlin
• Arrays in Kotlin are represented using the Array<T> class

• Arrays in Kotlin are immutable

• How can we create an Array ?


val namesArray = arrayOf("alex","ben", "chloe")

val emptyArray= emptyArray<String>()


Exceptions in Kotlin
• All Exception classes in Kotlin extends the Throwable class

• Exceptions are handled pretty much the standard way using the try-catch
block

• Kotlin does not have checked exceptions


Checked Exceptions
Java Kotlin

val file = File("file.txt")


val stream = FileInputStream(file)
Scope Functions
Scope Functions
• These functions are there in Kotlin to execute a piece of code within the
context of the object

• This functions form a temporary scope, that’s why the name


Scope Functions in Action
With Scope Function Without Scope Function

if(nameNullable!=null){
var nameNullable : String? = null
printName(nameNullable)
nameNullable?.run {
println(“Completed!")
printName(this)
}
println(“Completed!")

}
Scope Function accepts the lambda
Overview of the Application
• Build a Course Catalog Service
• RestFul API that manages the
course catalog for an online
learning platform
Course Catalog
• Use DB for storing the course Service
DB

Information
Automated Testing
Using JUnit5
Automated Tests
• Automated Tests plays a vital role in delivering quality Software

• Two types of Automated Tests:

• Integration Tests

• Unit Tests
Integration Tests
• Integration test is a kind of test which actually test the application end
to end

1 2 3

Integration
Controller Service Repository DB
Test
Unit Tests
• Unit test is a kind of test which tests only the class and method of interest
and mocks the next layer of the code

Unit Test Controller Service Mock Repository DB


Course Catalog Service
• `

CourseEntity
JSON
Course Catalog
Client DB
Service
CourseDTO
Course Catalog Service

Course Catalog
Client DB
Service

Postgres
H2
JVM related Kotlin Annotations
• @JvmOverloads - This is used to instruct the JVM to create the overloaded
version of methods when dealing with default values

• @JvmField - This is used to instruct the JVM to create the variable as a eld

• @JvmName - This is used to instruct the JVM to create a custom name for a
class or function

• @JvmStatic - This is used to expose the function that’s part of the


companion object or object as a static function

fi

You might also like