*定义*GraphQL 是一种用于 API 的查询语言,也是一种使用现有数据完成这些查询的运行时。GraphQL 为您的 API 中的数据提供了完整且易于理解的描述,使客户能够准确地询问他们需要什么,仅此而已,使 API 更容易随着时间的推移而发展,并支持强大的开发人员工具。

什么是 Netflix DGS?

Netflix DGS (Domain Graph Service) 是一个基于 Spring Boot 用 Kotlin 编写的 GraphQL 服务器框架,旨在将 Spring 框架之外的外部依赖降至最低。

DGS 还附带了代码生成插件,用于从 GraphQL Schema 生成 Java 或 Kotlin 代码。

GraphQL 初学者——从这里开始

img

GraphQL API 开发

GraphQL API 开发有以下两种方法

  1. Schema First API 开发*:这里我们使用 GraphQL 模式文件定义 API,并为 Query/Mutation*操作提供服务实现。
  2. Code First API 开发*:与上面相反,这里 GraohQL 模式是在运行时从代码定义生成的。*

Netflix DGS 更喜欢 Schema-first 开发而不是 code-first 方法。

GraphQL Schema Types(来自 GraphQL — 不特定于 DGS)

  1. 查询类型:定义只读操作(例如:GET)
  2. 突变类型:定义数据更改操作(例如:PUT、POST、DELETE、PATCH)
  3. 输入类型:定义用户定义的 json 类型,用作 Query/Mutation 操作的请求参数。
  4. 输出类型:定义用户定义的 json 类型,用作 Query/Mutation 操作的响应类型。
  5. 枚举类型:定义常量 — 可用于输入/输出类型中的属性。
  6. 标量类型:所有 GraphQL 默认基元类型都被视为标量。
  7. 接口类型:我们可以使用接口类型作为响应参数。

让我们从一个简单的例子开始:

img

[Spring初始化器Initializr 使用您快速启动所需的内容生成 spring boot 项目!start.spring.io](https://start.spring.io/#!type=maven-project&language=kotlin&platformVersion=2.4.5.RELEASE&packaging=jar&jvmVersion=11&groupId=com.shashir&artifactId=graphql-netflixdgs-springboot-app&name=graphql-netflixdgs-springboot-app&description=Build GraphQL server with Netflix DGS framework and Spring Boot&packageName=com.shashir.graphql-netflixdgs-springboot-app&dependencies=lombok,web,data-mongodb)

DGS 框架依赖项:(超链接附加)

  • 马文:
<dependency>
   <groupId>com.netflix.graphql.dgs</groupId>
   <artifactId>graphql-dgs-spring-boot-starter</artifactId>
   <!-- Set the latest framework version! -->
   <version>3.11.0</version>
</dependency>
  • 摇篮:
repositories {
    mavenCentral()
}dependencies {
    implementation "com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter:latest.release"
}
  • Gradle + Kotlin:
repositories {
    mavenCentral()
}dependencies {
    implementation("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter:latest.release")
}

让我们从 GraphQL 模式文件开始

在这里,我们使用几个模型对象——Account 和 Customer 来理解一些 GraphQL 概念及其在我们有多个具有休眠映射的实体时的用法。

这里我们有 Query、Mutation、Input、Enum 和 Scalar 类型

type Query {
    customers: [Customer]
}

type Mutation {
    customer(customerInput: CustomerInput): Customer
}

type Customer {
    customerNumber: String!
    name: String!
    gender: String!
    contact: Int!
    mail: String
    accounts: [Account]
}

type Account {
    accountId: String
    accountNumber: Int
    accountStatus: AccountStatus
    accountBalance: Float
}

input CustomerInput {
    name: String!
    gender: String!
    contact: Int!
    mail: String
    accounts: [AccountInput]
}

input AccountInput {
    accountNumber: Int
    accountStatus: AccountStatus
    accountBalance: Float
}

enum AccountStatus {
    Active, Inactive, Closed
}

使用 @DgsComponent 实现数据提取器

@DgsComponent — 它的作用类似于 @RestController 注释。

@DgsComponent
public class CustomerDataFetcher {

    @Autowired
    CustomerRepository customerRepository;

    @Autowired
    AccountRepository accountRepository;    @DgsData methods    @DgsMutation methods    @DgsQuery methods
}

*带有 @DgsQuery 和 @DgsData 注释的 GraphQL 查询*

*@DgsQuery* — 与 ‘@GetMapping’ 注释相同

它是一个方法级别的注释,用于使该方法成为数据提取器。它只有一个参数——“字段”。它将用于执行获取操作。

这里的 parentType 是“Query”——派生自注解本身和“field”——如果指定从提供的值中选取,否则它将派生自方法名称。

@DgsQuery(field = "customers")
public List<Customer> customers() {
    return customerRepository.findAll();
}

***@DgsData —***与 ‘@RequestMapping’ 注释相同

它是一个方法级别的注释,用于使该方法成为数据提取器。它有两个参数——“parentType”和“field”。

  • parentType — 它是一个包含字段的类型。
  • field — 表示 datafetcher 负责的字段。

这里要注意,参数’field’是一个可选参数,它会从方法名派生而来。

我们不能在单个方法中定义@DgsQuery 和@DgsMutation,而是可以将@DgsData 与parentType 一起使用为’Query’ 或’Mutation’。

@DgsData(parentType = "Query", field = "customers")
public List<Customer> customers() {
    return customerRepository.findAll();
}@DgsData(parentType = "Customer", field = "accounts")
public List<Account> accounts(DgsDataFetchingEnvironment dgsDataFetchingEnvironment) {
    Customer customer = dgsDataFetchingEnvironment.getSource();
    List<Account> accountList = new ArrayList<>();
    for (Account account : customer.getAccounts()) {
       Account accountResponse = accountRepository.findById(account.getAccountId()).get();
       accountList.add(accountResponse);
    }
    return accountList;
}

*带有@DgsMutation 注解的GraphQL Mutation*

***@DgsMutation —***与 ‘@PostMapping、@PutMapping、@DeleteMapping’ 注释相同

它是一个方法级别的注释,用于使该方法成为数据提取器。它只有一个参数——“字段”。它将用于执行持久化/更新/删除操作。

这里的 parentType 是“Mutation”——派生自注解本身和“field”——如果指定从提供的值中选取,否则它将派生自方法名称。

@DgsMutation
public Customer customer(CustomerInput customerInput) {
    Customer customer = Customer.builder()
            .contact(customerInput.getContact())
            .name(customerInput.getName())
            .gender(customerInput.getGender())
            .mail(customerInput.getMail())
 .accounts(mapCustomerAccounts(customerInput.getAccounts()))
            .build();
    Customer customerResponse = customerRepository.save(customer);
    return customerResponse;
}

让我们从 GraphiQL Web 控制台开始测试应用程序:

模型类——账户

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "account")
public class Account {    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String accountId;
    private Long accountNumber;
    private String accountStatus;
    private Double accountBalance;
}

模型类——客户

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Customer")
public class Customer {    @Id
    @Column(name = "CUSTOMER_NUMBER")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String customerNumber;
    private String name;
    private String gender;
    private Long contact;
    private String mail;    @OneToMany(cascade = CascadeType.ALL)
    private List<Account> accounts;
}

JPA 存储库 - 帐户和客户

@Repository
public interface CustomerRepository extends JpaRepository<Customer, String> {}@Repository
public interface AccountRepository extends JpaRepository<Account, String> {}

让我们从 GraphiQL Web 控制台开始测试应用程序:

img

通过选择“CustomerMutation”,我们正在执行 POST 操作,该操作会进入我们的 H2 数据库。

img

img

通过选择“CustomerQuery”,我们正在执行 GET 操作,我们正在从 H2 数据库中获取所有客户。

img

从 Netflix DGS 的基础知识开始,以及如何使用它来编写 GraphQL 组件以及如何使用它来实现查询和变异,并通过一个示例从 H2 DB 中持久化和读取数据。

上述示例的完整代码可以在 GitHub 上找到

https://github.com/shashirl9/neflixdgs-graphql-javaapp

https://github.com/Netflix/dgs-framework/blob/master/CONTRIBUTING.md