MiguelAngel_LV
MiguelAngel_LV

Reputation: 1258

Partial update REST in Spring Boot and Kotlin

I have a project with Spring Boot + Kotlin + Morphia.

I need add partial update of my entities. My actual post method:

   @PostMapping("update/")
    fun updateStudent(@RequestBody @Valid  student: Student, results: BindingResult): ResponseData<Student> {

        if (results.hasErrors())
            return ResponseData(errors = results.errors)


        if (!student.canEdit(login.user))
            return ResponseData()


        student.save()
        return ResponseData(data = student)
    }

I need read student from database and update only the sended fields

Upvotes: 0

Views: 1750

Answers (2)

Emily
Emily

Reputation: 346

This is my solution:

import org.springframework.beans.BeanWrapperImpl
import java.util.HashSet

fun getNullPropertyNames(source: Any): Array<String> {
    val src = BeanWrapperImpl(source)
    val pds = src.propertyDescriptors
    val emptyNames = HashSet<String>()
    for (pd in pds) {
        if (src.getPropertyValue(pd.name) == null) emptyNames.add(pd.name)
    }
    return emptyNames.toTypedArray()
}

And in controller

import org.springframework.beans.BeanUtils

@RestController
class GateController {

    @Autowired
    private val modelRepository: MyRepository? = null

    // allow both 'full' and 'partial' update
    @PutMapping("/somemodel/{Id}")
    fun updateModel(
            @PathVariable Id: Long,
            @RequestBody requestBody: SomeModel
    ): SomeModel {
        var objFromDb = modelRepository!!.findById(Id).orElseThrow { ResourceNotFoundException("Object not found with id: " + Id) }
        BeanUtils.copyProperties(requestBody, objFromDb, *getNullPropertyNames(requestBody))
        return modelRepository.save(objFromDb)
    }
...
}

Upvotes: 1

StanislavL
StanislavL

Reputation: 57381

There are 2 things to implement. Reading Student from DB and copying properties from the student from request.

I post java code but it's no problem to convert to kotlin

Morphia morphia = new Morphia();
db = new Mongo();
Datastore ds = morphia.createDatastore(db, appname, user, pass.toCharArray());

morphia.map(Student.class);
Student existing= ds.find(Student.class).field("id").equal(student.id).get(); 

Then you can use Apache BeanUtils

http://commons.apache.org/proper/commons-beanutils/javadocs/v1.8.3/apidocs/org/apache/commons/beanutils/BeanUtils.html#copyProperties%28java.lang.Object,%20java.lang.Object%29

 BeanUtils.copyProperties(existing, student);

then

existing.save();

Upvotes: 0

Related Questions