Part 1: Write Restful api with Kotlin & Spring Boot

Zahid Rasheed
6 min readApr 15, 2020

Being an android developer for 5 years I always wanted to learn how to write a Restful api by my own. It will be a fast phased tutorial/guide and it requires knowledge of kotlin and gradle. To keep it simple I have used spring boot so it also requires you to have IntelliJ IDEA. We will build a todo api from scratch and I will try to split it into multiple parts, so it is easy to follow.

You can set up a new project either directly through IntelliJ IDEA or Initializr Website. Let’s use spring initializr to create the application.

Summary:

  • We are going to work on a Gradle Project.
  • We will use kotlin as language.
  • To begin with, we new few basic dependencies. You can see the brief description under each dependency to find out why we need it.
  • Clicking GENERATE will download a todo.zip file, which you need to extract and then in the IDE, “File -> Open”, go into the extracted todo folder and press “Open”.

From Run -> “Run TodoApplication” (or press Ctrl + R). IDE will compile the project and you can see following messages in the console, which indicate that your application has started successfully.

Your application is running now at http://localhost:8080/. You can open this url in your browser which will likely end up on “Whitelabel Error Page”, because we don’t have any controller to handle requests. But I will call this our first success as we have successfully created a skeleton project which can also run in a browser.

Let’s first look at the generated code. There are 2 important things to look at:

Gradle:

Spring initializr get us build.gradle.kts file which is a Kotlin Gradle plugin file. Here we define all our dependencies and how to build the project. You can look into “Gradle Build” section here to find out why we need to add plugins and what compiler options we are using.

Application:

The Spring Initializr creates a simple application class for us.

@SpringBootApplication
class TodoApplication

fun main(args: Array<String>) {
runApplication<TodoApplication>(*args)
}

Annotations are backbone of Spring boot. By just adding annotations we can get a lot of work done. If we look at our application class we can see there is not much there. There is a main method that defines the starting point of our application. Then we have @SpringBootApplication annotation that adds all of the following:

@Configuration: Tags the class as a source of bean definitions for the application context.

@EnableAutoConfiguration: Tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.

@ComponentScan: Tells Spring to look for other components, configurations, and services in the com/example package, letting it find the controllers.

Webserver:

If you are wondering how pressing the run button gets you localhost? Each Spring Boot web application includes an embedded web server. The spring-boot-starter-web includes Tomcat by including spring-boot-starter-tomcat.

What about the port 8080? This is default port which you can change in application.properties file by adding:

server.port = 8088

Now we know briefly how to create a skeleton project and start the application, let’s add our RestController.

RestController:

@RestController indicates that the data returned by each method will be written straight into the response body instead of rendering a template.

@RestController is a convenience annotation for creating Restful controllers. It is a specialization of @Component and is autodetected through classpath scanning. It adds the @Controller and @ResponseBody annotations. It converts the response to JSON or XML.

Create a similar kotlin class and press run again. In your browser type http://localhost:8080/tasks and you will see a message “Work in progress”.

@RestController
class TodoController {

@GetMapping("/tasks")
fun getTasks(): ResponseEntity<String> {
return ResponseEntity.ok("Work in progress")
}
}

You can have any method name. The key part is what you put in @GetMapping as this define the path of end point.

Ok let’s create endpoints to add, delete and get tasks.

Entity:

First we need to define what is a Task. So we will make a data class called Task.

@Entity(name = "tasks")
data class Task(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = 0,
@get: NotBlank val title: String,
val description: String
)
  • By adding @Entity annotation we make this also a JPA entity.
  • By adding @Id @GeneratedValue we define that id of tasks will be automatically generated.
  • @get: NotBlank puts a check that, annotated element must not be null and must contain at least one non-whitespace character.

Repository:

Spring Data JPA focuses on using JPA to store data in a relational database. Its most compelling feature is the ability to create repository implementations automatically, at runtime, from a repository interface.

Now create a interface class TaskRepository.

@Repository
interface TasksRepository : JpaRepository<Task, Long>
  • By annotation the interface with @Repository we define this as a JPA repository class.
  • We extend it with JpaRepository, where Task is our entity and Long id type of primary key.

Let’s update our controller to use the repository to perform actions.

@RestController
class TodoController(@Autowired val repository: TasksRepository) {

@GetMapping("/tasks")
fun getTasks(): ResponseEntity<List<Task>> {
val tasks = repository.findAll()
return ResponseEntity.ok(tasks)
}

@GetMapping("/tasks/{id}")
fun getTask(@PathVariable id: Long): ResponseEntity<Task> {
return repository.findById(id).map {
ResponseEntity.ok(it)
}.orElse(
ResponseEntity.notFound().build()
)
}

@PostMapping("/tasks")
fun addTask(@RequestBody task: Task): ResponseEntity<Task> {
return ResponseEntity.ok(repository.save(task))
}

@DeleteMapping("/tasks/{id}")
fun deleteTask(@PathVariable id: Long): ResponseEntity<Void> {
repository.deleteById(id)
return ResponseEntity.noContent().build()
}
}

Key points:

  • We update the constructor of our class to provide the repository. By just adding @Autowired , spring boot will hook up the dependency for us.
  • Our repository is still an empty interface right? But we get all those basic operations for free by just extending JpaRepository. Later we will also see how we can extend the repository.
  • We need to pick up right annotations defining http methods i.e @GetMapping , @PostMapping , @DeleteMapping
  • @PathVariable are used to receive data via http methods.

Playtime:

Let’s run the application again. Now you can use Postman or any other tool to play with the api. Later we will also see how we can use springfox-swagger to generate the api documentation and also play with endpoints.

Let’s add our first task. Make sure you choose POST and then enter the end-point. In Body we will add json for Task entity. Press send and you will get the task back with auto assigned id.

To get list of all tasks, use the same endpoint as above and change the method to GET. This will list of all tasks.

To get a specific task, add the id of task in the endpoint.

To delete a task, change the type to DELETE and press send. Now when you get all tasks again, it will only return remaining task.

Next?

Conclusion:

Spring boot requires you to have IntelliJ IDEA to work but it is a super handy for beginners. It takes care of all boilerplate stuff and let you focus on the main part of your api.

--

--

Zahid Rasheed

A human. Being, Technology Freak, Sun hater; snow lover, Enjoys Photography, Live to Travel and Trying to be a better human being everyday.. http://zahid.cc