Simple CRUD Application using Ktor and React.js


To build a CRUD (Create, Read, Update, Delete) application using Ktor for the backend and React.js for the frontend, follow these steps:


1. Backend: Ktor

Setup Ktor Project

  1. Create a new Ktor project:

    • Use Ktor Project Generator or manually set it up.
    • Add dependencies for ktor-server-core, ktor-server-netty, ktor-server-content-negotiation, and ktor-serialization.
  2. Add the following dependencies in build.gradle.kts:

    implementation("io.ktor:ktor-server-core:2.x.x")
    implementation("io.ktor:ktor-server-netty:2.x.x")
    implementation("io.ktor:ktor-server-content-negotiation:2.x.x")
    implementation("io.ktor:ktor-serialization-kotlinx-json:2.x.x")
    implementation("ch.qos.logback:logback-classic:1.x.x") // For logging

Create Ktor Application

  • Define a simple API for managing resources.

File: Application.kt

package com.example

import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.request.*
import io.ktor.features.*
import io.ktor.routing.*
import io.ktor.serialization.*
import kotlinx.serialization.Serializable

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

@Serializable
data class Item(val id: Int, val name: String, val description: String)

val items = mutableListOf(
    Item(1, "Item1", "Description1"),
    Item(2, "Item2", "Description2")
)

fun Application.module() {
    install(ContentNegotiation) {
        json()
    }

    routing {
        route("/items") {
            get {
                call.respond(items)
            }
            get("/{id}") {
                val id = call.parameters["id"]?.toIntOrNull()
                val item = items.find { it.id == id }
                if (item == null) call.respond(HttpStatusCode.NotFound, "Item not found")
                else call.respond(item)
            }
            post {
                val item = call.receive<Item>()
                items.add(item)
                call.respond(HttpStatusCode.Created, item)
            }
            put("/{id}") {
                val id = call.parameters["id"]?.toIntOrNull()
                val updatedItem = call.receive<Item>()
                val index = items.indexOfFirst { it.id == id }
                if (index == -1) call.respond(HttpStatusCode.NotFound, "Item not found")
                else {
                    items[index] = updatedItem
                    call.respond(HttpStatusCode.OK, updatedItem)
                }
            }
            delete("/{id}") {
                val id = call.parameters["id"]?.toIntOrNull()
                if (items.removeIf { it.id == id }) call.respond(HttpStatusCode.NoContent)
                else call.respond(HttpStatusCode.NotFound, "Item not found")
            }
        }
    }
}

2. Frontend: React.js

Setup React Project

  1. Create a new React app:

    npx create-react-app ktor-react-crud
    cd ktor-react-crud
  2. Install dependencies:

    npm install axios

Create React Components

File: src/App.js

import React, { useState, useEffect } from "react";
import axios from "axios";

const API_URL = "http://localhost:8080/items";

function App() {
  const [items, setItems] = useState([]);
  const [newItem, setNewItem] = useState({ id: "", name: "", description: "" });

  useEffect(() => {
    fetchItems();
  }, []);

  const fetchItems = async () => {
    try {
      const response = await axios.get(API_URL);
      setItems(response.data);
    } catch (error) {
      console.error("Error fetching items:", error);
    }
  };

  const addItem = async () => {
    try {
      await axios.post(API_URL, newItem);
      fetchItems();
      setNewItem({ id: "", name: "", description: "" });
    } catch (error) {
      console.error("Error adding item:", error);
    }
  };

  const updateItem = async (id) => {
    try {
      await axios.put(`${API_URL}/${id}`, newItem);
      fetchItems();
      setNewItem({ id: "", name: "", description: "" });
    } catch (error) {
      console.error("Error updating item:", error);
    }
  };

  const deleteItem = async (id) => {
    try {
      await axios.delete(`${API_URL}/${id}`);
      fetchItems();
    } catch (error) {
      console.error("Error deleting item:", error);
    }
  };

  return (
    <div>
      <h1>Ktor + React CRUD</h1>
      <div>
        <input
          type="text"
          placeholder="ID"
          value={newItem.id}
          onChange={(e) => setNewItem({ ...newItem, id: e.target.value })}
        />
        <input
          type="text"
          placeholder="Name"
          value={newItem.name}
          onChange={(e) => setNewItem({ ...newItem, name: e.target.value })}
        />
        <input
          type="text"
          placeholder="Description"
          value={newItem.description}
          onChange={(e) => setNewItem({ ...newItem, description: e.target.value })}
        />
        <button onClick={addItem}>Add Item</button>
        <button onClick={() => updateItem(newItem.id)}>Update Item</button>
      </div>
      <ul>
        {items.map((item) => (
          <li key={item.id}>
            {item.name} - {item.description}
            <button onClick={() => deleteItem(item.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

3. Running the Application

  1. Run Ktor Backend:

    • Start the server using:
      ./gradlew run
    • The API will be available at http://localhost:8080.
  2. Run React Frontend:

    • Start the React app:
      npm start
    • Open http://localhost:3000 in your browser.

4. Test the Application

  • Use the React UI to create, read, update, and delete items.
  • The actions will be reflected in the Ktor backend.

This example demonstrates how to connect Ktor and React.js for a seamless CRUD application. 

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete