Spring Boot Dersleri : HATEOAS Nedir? HATEOAS Uygulama Örneği Kullanımı
Spring Boot Dersleri‘ne devam ediyoruz.
Nedir?
Spring Boot projelerimizde kullandığımız Rest işlemlerinde kullanımı ve dökümante edilmesini sağlayan Hypermedia As The Engine Of Application State‘un kısaltması olan HATEOAS‘ı bu yazıda inceleyeceğiz.
Bir rest servisinin response üzerinden tüm içerik bilgilerini görebildiğimiz başka bir kaynağa ya da dökümana gerek kalmadan kullanabilmeye olanak sağlayan bir araçtır. Örnek verecek olursam bir kişinin kaydını getirmek için rest üzerinden gelen cevabın içerisinde o restin diğer yapabileceği tüm yeteneklerinde görülebileceği bir yapı sağlamaktadır. Projemizde başka Rest işlemleri eklediysek silme, güncelleme gibi işlemleri yapabilmek için hangi rest yolunun kullanılması gerektiği gibi bilgileri görüntüler.
Spring Boot içerisinde HATEOAS kullanmak için Maven bağımlılığını kullanarak ekleyebiliriz.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-hateoas</artifactId> </dependency>
Spring Boot Rest projesi için HATEOAS’ı kullanarak bir proje yapalım.
Örnek Uygulama
Bir öğrenci uygulaması yapalım. Öğrenci bilgilerini getiren ve silme işlemini gerçekleştiren bir Spring Boot Rest uygulaması yapacağız.
Maven bağımlılığı kullanarak projeyi geliştireceğiz. Gerekli olan bağımlılıklarımızın yer aldığı pom.xml dosyamız aşağıdaki gibi olacak.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.hateoas</groupId> <artifactId>spring-hateoas</artifactId> <version>0.25.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.plugin</groupId> <artifactId>spring-plugin-core</artifactId> <version>1.2.0.RELEASE</version> </dependency>
Maven bağımlılığımız bu şekildedir.
Öğrenci classımızı oluşturalım.
@Entity public class Student extends ResourceSupport { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long studentId; private String firstName; private String lastName; public Student() { } public Student(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public Long getStudentId() { return studentId; } public void setStudentId(Long studentId) { this.studentId = studentId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Student Controllerimizi oluşturalım. Controllerimiz RestControllerimiz yapısında olacak.
@RestController public class StudentController { @Autowired StudentService studentService; @GetMapping(value = "/student/{id}", produces = {"application/hal+json"}) public Resource<Student> getStudent(@PathVariable(value = "id", required = true) Long id) { Student student = studentService.getStudentById(id) student.add(linkTo(methodOn(StudentController.class).getStudent(id)).withSelfRel().withType("GET")); return new Resource<Student>(student); } @GetMapping(value = "/student", produces = {"application/hal+json"}) public Resources<Student> getStudents() { List<Student> students = studentService.getAllStudent(); for (Student student : students) { Long studentId = student.getStudentId(); student.add(linkTo(methodOn(StudentController.class).getStudent(studentId)).withRel("get_student").withType("GET")); student.add(linkTo(methodOn(StudentController.class).deleteStudent(studentId)).withRel("delete_student").withType("DELETE")); } Link link = linkTo(methodOn(StudentController.class).getStudents()).withSelfRel().withType("GET"); return new Resources<Student>(students, link); } @DeleteMapping(value = "/student/{id}", produces = {"application/hal+json"}) public Resource<Student> deleteStudent(@PathVariable(value = "id", required = true) Long id) { Optional<Student> student = studentService.getStudentById(id); studentService.deleteStudentById(id); Student student = new Student(); student.add(linkTo(methodOn(StudentController.class).getStudents()).withRel("get_students").withType("GET")); return new Resource<Student>(student); } }
RestControllerimiz’e HATEOAS yeteneklerini controllerimizde kullanarak ekliyoruz.
student.add(linkTo(methodOn(StudentController.class).getStudent(studentId)).withRel("get_student").withType("GET")); student.add(linkTo(methodOn(StudentController.class).deleteStudent(studentId)).withRel("delete_student").withType("DELETE"));
Yukarıdaki satırlar Rest servisimizinden HATEOAS özelliğini kullanarak Rest servisimizin özelliklerini tanımlayarak istek yapacak kişiye bu bilgilerin gönderilmesini sağlamaktayız. Bu satırları açıklayayım.
methodOn: Gelen isteğin kullanılacağı class ve hangi metodun hangi parametre alarak işlem yapacağını belirtir.
with_rel: Metod ile ilgili referans tanımlaması yapılır.
withType: Hangi Rest tipinde olduğunun tanımı yapılmaktadır.İstek yapan kişiye bilgi vermek için kullanılır.
Sonuç olarak cevap olarak dönen rest servisinde şu şekilde bilgiler gözükür.
"studentList": [ { "studentId": 1, "firstName": "Burak", "lastName": "KUTBAY", "_links": { "get_student": { "href": "http://localhost:8080/student/1", "type": "GET" }, "delete_student": { "href": "http://localhost:8080/student/1", "type": "DELETE" } } }, ] }, "_links": { "self": { "href": "http://localhost:8080/students", "type": "GET" } } }
Bilgileri istek yapana gözükerek dökümantasyonu oluşmaktadır.
Önceki Ders: Context Path Değiştirmek | Spring Boot Dersleri | Sonraki Ders: |
Merhabalar hocam . bende Spring öğrenmek istiyorum. yalnız şu an sadece JavaSE bilgim mevcut JavaEE ne geçerken direk Spring ile mi başlamak lazım yoksa jsp ile mi ? . nasıl bir yol çiz meliyim ?
jsp ile başlamana gerek yok.
Spring Boot ile başlayabilirsin. Öğrenmesi, kullanması(configuration) oldukça basit.