Type Query trong GraphQL với Spring Boot

2867

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Trong bài viết trước, mình đã giới thiệu với các bạn về GraphQL, những vấn đề mà GraphQL đã giải quyết được cho những hạn chế của RESTful Web Service. Mình cũng đã hướng dẫn  sơ qua cho các bạn về cách hiện thực type Query của GraphQL với Spring Boot. Trong bài viết này, chúng ta sẽ tìm hiểu chi tiết hơn về cách hiện thực type Query này sử dụng Spring Boot các bạn nhé!

Đầu tiên, mình sẽ tạo một Spring Boot project với Web và GraphQL Starter để làm ví dụ:

Kết quả:

Như mình đã nói trong bài viết trước, để làm việc với GraphQL, chúng ta cần định nghĩa các tập tin schema .graphqls. Mặc định thì Spring Boot sẽ scan tất cả các thư mục trong classpath src/main/resources của project để đọc các tập tin schema này.

Mình sẽ tạo một thư mục tên là graphql trong thư mục src/main/resources và để các tập tin schema của GraphQL trong thư mục này.

Để làm ví dụ mình đã tạo mới tập tin schema.graphqls với nội dung ban đầu đơn giản như sau:

type Query {
  hello: String
}

Query này sẽ return dòng chữ “Hello World” khi chúng ta query tới!

Để handle cho Query trên, chúng ta sẽ tạo mới một controller và định nghĩa một method có tên giống với tên field của type Query này, như sau:

package com.huongdanjava.graphql;
 
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
 
@Controller
public class GraphQLController {
 
  @QueryMapping
  public String hello() {
    return "Hello World";
  }
}

Như các bạn thấy, phương thức hello() đã được annotate với annotation @QueryMapping giúp cho Spring có thể scan và map tên method này với field của type Query. Rất đơn giản phải không các bạn?

Behind the sense, thì annotation @QueryMapping được implement sử dụng một generic annotation là @SchemaMapping:

Annotation @SchemaMapping này định nghĩa một thuộc tính là typeName cho phép chúng ta định nghĩa type của GraphQL. Ở đây, type của chúng ta là Query đó các bạn!

Một thuộc tính khác của annotation @SchemaMapping là field, giúp Spring có thể map field của GraphQL với tên method sẽ handle request:

Mặc định nếu chúng ta không khai báo giá trị cho thuộc tính field này, giá trị của nó sẽ là tên method các bạn nhé!

Tuyển dụng lập trình viên Java đãi ngộ hấp dẫn, xem thêm tại đây!

Nếu không sử dụng annotation @QueryMapping, chúng ta có thể viết lại code ở trên sử dụng annotation @SchemaMapping như sau:

package com.huongdanjava.graphql;

import org.springframework.graphql.data.method.annotation.SchemaMapping;
import org.springframework.stereotype.Controller;
 
@Controller
public class GraphQLController {

  @SchemaMapping(typeName = "Query", field = "hello")
  public String hello() {
    return "Hello World";
  }
}

Để tiện cho việc testing, chúng ta sẽ thêm property spring.graphql.graphiql.enabled=true để enable sử dụng công cụ GraphiQL, trong tập tin application.properties:

spring.graphql.graphiql.enabled=true

Bây giờ, nếu chạy ứng dụng này và query sử dụng field hello trên, các bạn sẽ thấy kết quả như sau:

Để truyền tham số cho một Query, chúng ta sẽ định nghĩa ví dụ như sau:

type Query {
  hello(name: String): String
}

Trong controller, chúng ta sẽ sử dụng annotation @Argument để bind tham số được định nghĩa trong field của Query với tham số trong method handle request:

package com.huongdanjava.graphql;
 
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
 
@Controller
public class GraphQLController {
 
  @QueryMapping
  public String hello(@Argument("name") String name) {
    return "Hello, " + name;
  }
}

Thuộc tính name của annotation @Argument này cho phép chúng ta chỉ định rõ tham số trong method được bind với tham số nào trong Query.

Kết quả khi chúng ta query:

{
  hello(name: "Khanh")
}

như sau:

Bài viết gốc được đăng tải tại huongdanjava.com

Xem thêm:

Ứng tuyển ngay việc làm IT lương cao trên TopDev!