如何更新資料

在 GraphQL 中,新增或更新資料叫 Mutation。底下示範簡單的更新資料語法:

mutation{
  updateEmployee(id: 1, age: 33, name: "aaa3")
  {
    name
    age
  }
}

如上所示,在更新 employee 資料時,是用三個參數來傳,底下的 subquery 是顯示更新後的資料,當然還有另一種比較明確易讀的方式:

mutation{
  updateEmployee(id: 1, age: 33, name: "aaa3")
  {
    name
    age
  }
  updateCompany(company:{
    id: 1
    name: "aaa3"
    desc: "eeeee"
  })
  {
    name
  }
}

可以直接用類似一個物件的方式,裡面放各屬性的資料,接下來講解實作細節:

首先實作CompanyInputType,它繼承InputObjectGraphType,這是給外部當參數用的:

public class CompanyInputType: InputObjectGraphType<Company>
{
    public CompanyInputType()
    {
        Name = "CompanyInput";
        Field(x => x.Id, type: typeof(IdGraphType)).Description("...");
        Field(x => x.Name).Description("...");
        Field(x => x.Desc).Description("...");
    }
}

接下來是實作兩個 update 的方法,分別更新 employee 跟 company 物件,第一個是傳一般型態的參數,第二個是傳一個物件:

public class MainMutation : ObjectGraphType
{
    public MainMutation(IEmployeeRepository employeeRepository, ICompanyRepository companyRepository)
    {
        Name = "Mutation";

        Field<EmployeeType>(
            "updateEmployee",
            arguments: new QueryArguments(
                new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "id" },
                new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "age" },
                new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "name" }
            ),
            resolve: context =>
            {
                int id = context.GetArgument<int>("id");
                int age = context.GetArgument<int>("age");
                string name = context.GetArgument<string>("name");
                Employee employee = new Employee { Id = id, Age = age, Name = name };
                employee = employeeRepository.UpdateEmployee(employee);
                return employee;
            });

        Field<CompanyType>(
            "updateCompany",
            arguments: new QueryArguments(
                new QueryArgument<NonNullGraphType<CompanyInputType>> { Name = "company" }
            ),
            resolve: context =>
            {
                Company data = context.GetArgument<Company>("company");
                Company company = new Company
                {
                    Id = data.Id,
                    Name = data.Name,
                    Desc = data.Desc
                };
                company = companyRepository.UpdateCompany(company);
                return company;
            });
    }
}

大致上的結構就是這樣,其實不會太難,只是要實作複雜的 GraphQL 語法,很考驗做架構的能力。

參考資料