How To Set Up CRUD Methods In The Webserver

Hello together,

as you may know, I am writing a game "Hammurabi", which shall be connected to Hive someday.

This post bases on Implementation of Swagger.io und Postman to Springboot.

Here I want to show what I did, to enhance the functionality of the Webserver. Until now it only supports get requests (read).
I also want to be able to Create, (Read), Update and Delete (CRUD) my data-set.

Create

To enable create, in the controller we need to refer to the repository-Interface. For this we create the new propertiy "userlogrepository" from the type UserlogRepository and make it public to Spring by marking it with "@Autowired":

@Autowired
UserlogRepository userlogrepository;

grafik.png

The second thing we need to do is to add the @Postmapping method, which creates a new userlog-Entry:

//Create -----------------------------------------------------------------
@PostMapping(value = "/userlogs")
public UserlogEntity newUserlog (@RequestBody UserlogEntity newUserlog)
{
    return userlogrepository.save(newUserlog);
}

Here is the complete UserlogController file (so far):

package org.chary.controller;

import org.chary.dto.Userlogdto;
import org.chary.entity.UserlogEntity;
import org.chary.repository.UserlogRepository;
import org.chary.services.UserlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

@RestController
@CrossOrigin("*")
@RequestMapping("/userlogcontroller")
public class UserlogController {

    @Autowired
    UserlogService userlogservice;  // Giving the interface to Spring.
    // Spring searches for a corresponding class and finds UserlogserviceImpl
    // Spring creates an instance of it and puts it into userlogservice

    @Autowired
    UserlogRepository userlogrepository;

    //Read -----------------------------------------------------------------
    @GetMapping(value = "/userlogs")  //curl -X -get http://localhost:8099/userlogcontroller/userlogs"
    public List<Userlogdto> getAllUserlogs() {
        System.out.println("Hier sind alle Userlog-Einträge: " + userlogservice.getAllUserlogs().toString());
        return userlogservice.getAllUserlogs();

    }

    @GetMapping(value = "/welcome")
    public String welcome() {
        return "Welcome to the Hamurabi-Game - Written by Achim Mertens";
    }

    //Create -----------------------------------------------------------------
    @PostMapping(value = "/userlogs")
    public UserlogEntity newUserlog (@RequestBody UserlogEntity newUserlog)
    {
        return userlogrepository.save(newUserlog);
    }
}

Now we can send data via curl:

C:\Users\User>curl -v -X POST http://localhost:8099/userlogcontroller/userlogs -H "Content-Type:application/json" -d "{\"id\":\"6\",\"username\":\"AxelSchweiss\",\"logintime\":\"2022-02-02 12:16\"}"

grafik.png

Or we can do it via Postman:

grafik.png

Read single value

Now I want to add the possibility to get only one data set.
I have added the following part into the controller:

        // Read Single Item
    @GetMapping(value = "/userlog/{id}")
        public Optional<UserlogEntity> one (@PathVariable String id)
        {
            return userlogrepository.findById(id);
        }

(I also changed the Type of the id from Integer to String.
(Which caused the error: Unknown integral data type for ids : java.lang.String. I had to comment out @GeneratedValue in the UserlogEntity class:
@Id
//@GeneratedValue is only allowed if ID is from type integer
))

To read the first dataset insert into the command line:

curl -v -X GET http://localhost:8099/userlogcontroller/userlog/1 -H "Content-Type:application/json"

grafik.png

Update

To get the feature, that the data can be updated, we add the following into UserController class:

    //Update ----------------------------------------------------------------
    //The object "userlogEntity" is automatecally created by Spring, so we don't need an instantiation here anywhere
    //The result of "userlogEntity" is copied into "userlogEntity"
    @PutMapping("/userlogs/{id}")
    public UserlogEntity replaceUserlog(@RequestBody UserlogEntity replaceUserlog, @PathVariable String id) {
        return userlogrepository.findById(id).map(userlogEntity -> {
                    userlogEntity.setUsername(replaceUserlog.getUsername());
                    userlogEntity.setLogintime(replaceUserlog.getLogintime());
                    return userlogrepository.save(userlogEntity);     })
                .orElseGet( () -> {
                    replaceUserlog.setId(id);
                    return userlogrepository.save(replaceUserlog);
                });
    }

After restarting the server, we are able to update some data, here the logindate of the dataset from ID=4:

grafik.png
And here we change a complete dataset (with ID=2) via postman:

grafik.png

Delete

We add the following to the controllerclass:

    /**
     * //Delete --------------------------------------------------------------------
     * curl -v -X GET http://localhost:8099/userlogcontroller/userlog/17 -H "Content-Type:application/json"
     **/
    @DeleteMapping("userlog/{id}")
    void delteUserlog(@PathVariable String id) {
        if (userlogrepository.findById(id).isPresent()) {
            userlogrepository.deleteById(id);
        }
    }

After rebooting we can delete a user:
grafik.png
Same with Postman:

grafik.png

At the end, our userlogcontroller looks like this:

package org.chary.controller;

import org.chary.dto.Userlogdto;
import org.chary.entity.UserlogEntity;
import org.chary.repository.UserlogRepository;
import org.chary.services.UserlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@CrossOrigin("*")
@RequestMapping("/userlogcontroller")
public class UserlogController {

    @Autowired
    UserlogService userlogservice;  // Giving the interface to Spring.
    // Spring searches for a corresponding class and finds UserlogserviceImpl
    // Spring creates an instance of it and puts it into userlogservice

    @Autowired
    UserlogRepository userlogrepository;

    /**
     * //Read -----------------------------------------------------------------
     * //curl -X -get http://localhost:8099/userlogcontroller/userlogs"
     **/
    @GetMapping(value = "/userlogs")
    public List<Userlogdto> getAllUserlogs() {
        System.out.println("Hier sind alle Userlog-Einträge: " + userlogservice.getAllUserlogs().toString());
        return userlogservice.getAllUserlogs();
    }

    /**
     * // Read Single Item
     * curl -v -X GET http://localhost:8099/userlogcontroller/userlog/17 -H "Content-Type:application/json"
     **/
    @GetMapping(value = "/userlog/{id}")
    public Optional<UserlogEntity> one(@PathVariable String id) {
        return userlogrepository.findById(id);
    }


    @GetMapping(value = "/welcome")
    public String welcome() {
        return "Welcome to the Hamurabi-Game - Written by Achim Mertens";
    }

    /**
     * //Create -----------------------------------------------------------------
     * // curl -v -X POST http://localhost:8099/userlogcontroller/userlogs -H "Content-Type:application/json" -d "{\"id\":\"17\",\"username\":\"DickTat\",\"logintime\":\"2022-02-04 12:16\"}"
     */
    @PostMapping(value = "/userlogs")
    public UserlogEntity newUserlog(@RequestBody UserlogEntity newUserlog) {
        return userlogrepository.save(newUserlog);
    }

    /**
     * //Update ----------------------------------------------------------------
     * The object "userlogEntity" is automatecally created by Spring, so we don't need an instantiation here anywhere
     * The result of "userlogEntity" is copied into "userlogEntity"
     * Example:
     * curl --location --request PUT 'localhost:8099/userlogcontroller/userlogs/2' \
     * --header 'Content-Type: application/json' \
     * --data-raw '  {"id": "2","username": "AtzeTon","logintime": "2022-01-31 14:16:00"}'
     */
    @PutMapping("/userlogs/{id}")
    public UserlogEntity replaceUserlog(@RequestBody UserlogEntity replaceUserlog, @PathVariable String id) {
        return userlogrepository.findById(id).map(userlogEntity -> {
                    userlogEntity.setUsername(replaceUserlog.getUsername());
                    userlogEntity.setLogintime(replaceUserlog.getLogintime());
                    return userlogrepository.save(userlogEntity);
                })
                .orElseGet(() -> {
                    replaceUserlog.setId(id);
                    return userlogrepository.save(replaceUserlog);
                });
    }

    /**
     * //Delete --------------------------------------------------------------------
     * curl -v -X GET http://localhost:8099/userlogcontroller/userlog/17 -H "Content-Type:application/json"
     **/
    @DeleteMapping("userlog/{id}")
    void delteUserlog(@PathVariable String id) {
        if (userlogrepository.findById(id).isPresent()) {
            userlogrepository.deleteById(id);
        }
    }

}

So with this, we have a server, which

  • is connected to a H2 database,
  • has a swagger interface
  • can (C)reate data via http
  • can (R)ead the data via http
  • can (U)pdate data via http
  • can (D)elete data via http

One can see all features via the swagger-ui:

grafik.png

My Code is public available at github: https://github.com/achimmertens/Hamurabi

The next step is, that the server learns to read data from other API-REST servers. So stay tuned.

Regards, Achim

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now