GraphQLのお気軽お試しコード

最近たまにGraphQLを触ってました。せっかくなので備忘録的にお試し用の簡単に試せるコードを残しておきます。本来はexpress-graphql等を使ってHTTP経由でアクセスすると思いますが、このコードは直接APIでアクセスして結果を取得してます。GraphQL自体がどのような動きをするのか確認するのに試しやすいと思います。

サンプルコードの内容

GraphQLのスキーマはAPIではなく、GraphQL Schema Languageを利用して記述しています。スキーマを直接インスタンス化するのにApollo社のgraphql-toolsを利用しています。

流れとしては下記のような感じです。

  • Schema Languageでtypeを定義する
  • 定義したtypeに対応するresoloverを作成する
  • 上記を組み合わせたschemaインスタンスを作成する

その後、このschemaに対してqueryと呼ばれる問い合わせと、mutationと呼ばれるデータ更新を行っています。

サンプルコード

const graphql = require('graphql');
const tools = require('graphql-tools');

const companies = [
  {
    id: 1,
    name: 'A company'
  },
  {
    id: 2,
    name: "B company"
  }
];

const employees = [
  {
    id: 1,
    company_id: 1,
    name: 'Mr. A',
  },
  {
    id: 2,
    company_id: 1,
    name: 'Mr. B',
  },
  {
    id: 3,
    company_id: 2,
    name: 'Mr. C',
  }
];

const typeDefs = `
  type Company {
    id: ID!
    name: String
    employees: [Employee]
    sales: Int
  }
  
  type Employee {
    id: ID!
    name: String
    company: Company
  }
  
  type Query {
    getCompanies: [Company]
    getCompany (id: ID!): Company
  }
  
  input CompanyInput {
    name: String!
  }
  
  input EmployeeInput {
    company_id: ID!
    name: String!
  }
  
  type Mutation {
    addCompany (company: CompanyInput): Company
    addEmployee (employee: EmployeeInput): Employee
  }
`;

const resolvers = {
  Company: {
    sales: (company, args, context) => {
      return Math.random() * 100
    },
    employees: (company, args, context) => {
      return employees.filter(e => +e.company_id === +company.id);
    }
  },
  Employee: {
    company: (employee, args, context) => {
      return companies.find(c => +c.id == +employee.company_id);
    }
  },
  Query: {
    getCompanies(container, args, ctx, info) {
      if (args && args.id) {
        return companies.filter(c => +args.id === +c.id);
      }
      return companies;
    },
    getCompany(container, args, ctx, info) {
      return companies.find(c => +args.id === +c.id);
    }
  },
  Mutation: {
    addCompany (mutation, args) {
      const id = companies.length + 1;
      companies.push({
        id,
        name: args.company.name,
      });
      return companies.find(c => +c.id === +id);
    },
    addEmployee (mutation, args) {
      const id = employees.length + 1;
      employees.push({
        id,
        company_id: args.employee.company_id,
        name: args.employee.name,
      });
      return employees.find(e => +e.id === +id);
    }
  },
};

const schema = tools.makeExecutableSchema({typeDefs, resolvers});

const gql = `
{
  company: getCompanies {
    id
    name
    sales
    employees {
      id
      name
    }
  }
}
`;
graphql.graphql(schema, gql, null, null, {id: 1}).then(result => {
  console.log('1, QUERY', JSON.stringify(result, null, 2));

  const gql = `
mutation example($company: CompanyInput!) {
  company: addCompany(company: $company) {
    id
    name
    sales
  }
}
`;
  graphql.graphql(schema, gql, null, null, {company: {name: 'C company(NEW)'}}).then(result => {
    console.log('2, MUTATION', JSON.stringify(result, null, 2));

    const gql = `
mutation example($employee: EmployeeInput!) {
  employee: addEmployee(employee: $employee) {
    id
    name
  }
}
`;
    graphql.graphql(schema, gql, null, null, {employee: {company_id: 3, name: 'Mr. D(NEW)'}}).then(result => {
      console.log('3, MUTATION', JSON.stringify(result, null, 2));

      const gql = `
query example($id: ID!) {
  company: getCompany(id: $id) {
    id
    name
    sales
    employees {
      id
      name
    }
  }
}
`;
      graphql.graphql(schema, gql, null, null, {id: 3}).then(result => {
        console.log('4, QUERY', JSON.stringify(result, null, 2));
      });
    });
  });
});

実行結果

試すには、node foo.jsします。実行に予めgraphqlとgraphql-toolsをnpm installしておきます。

実行結果は下記のようになります。

1, QUERY {
  "data": {
    "company": [
      {
        "id": "1",
        "name": "A company",
        "sales": 64,
        "employees": [
          {
            "id": "1",
            "name": "Mr. A"
          },
          {
            "id": "2",
            "name": "Mr. B"
          }
        ]
      },
      {
        "id": "2",
        "name": "B company",
        "sales": 25,
        "employees": [
          {
            "id": "3",
            "name": "Mr. C"
          }
        ]
      }
    ]
  }
}
2, MUTATION {
  "data": {
    "company": {
      "id": "3",
      "name": "C company(NEW)",
      "sales": 33
    }
  }
}
3, MUTATION {
  "data": {
    "employee": {
      "id": "4",
      "name": "Mr. D(NEW)"
    }
  }
}
4, QUERY {
  "data": {
    "company": {
      "id": "3",
      "name": "C company(NEW)",
      "sales": 4,
      "employees": [
        {
          "id": "4",
          "name": "Mr. D(NEW)"
        }
      ]
    }
  }
}