С помощью GraphQL мы можем создавать скалярные типы, как мы это делаем с типами объектов и другими составными типами данных.

В этой статье мы рассмотрим, как создавать типы ввода GraphQL с помощью конструктора GraphQLInputObjectType.

Конструктор GraphQLInputObjectType

Мы можем использовать конструктор GraphQLInputObjectType для создания нового типа ввода.

Для этого мы передаем объект в конструктор GraphQLInputObjectType со свойством name, чтобы установить имя нашего типа ввода, а затем объект fields с именами полей в качестве ключей, а значения являются объектами со свойством type, чтобы указать типы полей.

Чтобы указать обязательное поле, мы используем конструктор GraphQLNonNull. Кроме того, мы можем указать значение по умолчанию, указав значение для свойства defaultValue.

Например, мы можем указать мутацию следующим образом:

const express = require('express');
const graphqlHTTP = require('express-graphql');
const graphql = require('graphql');
class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}
const PersonInputType = new graphql.GraphQLInputObjectType({
  name: 'PersonInput',
  fields: {
    firstName: { type: new graphql.GraphQLNonNull(graphql.GraphQLString) },
    lastName: { type: new graphql.GraphQLNonNull(graphql.GraphQLString) },
  }
});
const PersonType = new graphql.GraphQLObjectType({
  name: 'Person',
  fields: {
    firstName: { type: graphql.GraphQLString },
    lastName: { type: graphql.GraphQLString },
  }
});
let person = new Person('Jane', 'Smith');
const mutationType = new graphql.GraphQLObjectType({
  name: 'Mutation',
  fields: {
    createPerson: {
      type: PersonType,
      args: {
        person: {
          type: new graphql.GraphQLNonNull(PersonInputType),
        },
      },
      resolve: (_, { person: { firstName, lastName } }) => {
        person = new Person(firstName, lastName);
        return person;
      }
    }
  }
});
const queryType = new graphql.GraphQLObjectType({
  name: 'Query',
  fields: {
    person: {
      type: PersonType,
      resolve: () => {
        return person;
      }
    }
  }
});
const schema = new graphql.GraphQLSchema({ query: queryType, mutation: mutationType });
const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  graphiql: true,
}));
app.listen(3000, () => console.log('server started'));

В приведенном выше коде мы создали тип ввода PersonInputType следующим образом:

const PersonInputType = new graphql.GraphQLInputObjectType({
  name: 'PersonInput',
  fields: {
    firstName: { type: new graphql.GraphQLNonNull(graphql.GraphQLString) },
    lastName: { type: new graphql.GraphQLNonNull(graphql.GraphQLString) },
  }
});

Мы использовали конструктор GraphQLInputObjectType и передаем объект с полем name со значением 'PersonInput', чтобы указать имя типа.

Затем в свойстве fields мы указали, что тип имеет поля firstName и lastName, каждое из которых является обязательным, поскольку мы использовали конструктор GraphQLNonNull с переданным в него типом GraphQLString.

Типы ввода можно использовать только с мутациями.

Затем мы создаем мутацию, которая принимает аргумент PersonInputType следующим образом:

const mutationType = new graphql.GraphQLObjectType({
  name: 'Mutation',
  fields: {
    createPerson: {
      type: PersonType,
      args: {
        person: {
          type: new graphql.GraphQLNonNull(PersonInputType),
        },
      },
      resolve: (_, { person: { firstName, lastName } }) => {
        person = new Person(firstName, lastName);
        return person;
      }
    }
  }
});

В приведенном выше коде мы создали createPerson мутацию с type, определяющим тип вывода, которым является PersonType, который мы указали в коде.

В свойстве args мы указали аргумент person с type, установленным на PersonInputType. Это указывает, что мутация out принимает объект типа ввода PersonInuptType.

Затем в нашей функции resolve мы получаем firstName и lastName из параметра args во втором параметре и создали новый объект Person, установили для него значение person и вернули его.

Все серверные приложения GraphQL должны иметь тип корневого запроса, поэтому мы также указали queryType следующим образом:

const queryType = new graphql.GraphQLObjectType({
  name: 'Query',
  fields: {
    person: {
      type: PersonType,
      resolve: () => {
        return person;
      }
    }
  }
});

Мы возвращаем объект Person и возвращаем переменную person.

Затем, когда мы сделаем мутацию следующим образом:

mutation {
  createPerson(person: {firstName: "John", lastName: "Doe"}){
    firstName
    lastName
  }
}

Мы получаем:

{
  "data": {
    "createPerson": {
      "firstName": "John",
      "lastName": "Doe"
    }
  }
}

как ответ.

Когда мы делаем следующий запрос:

{
  person {
    firstName
    lastName
  }
}

Возвращаемся:

{
  "data": {
    "person": {
      "firstName": "John",
      "lastName": "Doe"
    }
  }
}

Заключение

Мы можем создать тип ввода GraphQL с конструктором GraphQLInputObjectType со свойствами name и fields, переданными вместе в один объект в конструктор.

Поле name имеет имя, а объект fields - поля и тип.

Мы можем использовать GraphQLNonNull, чтобы указать, что поле является обязательным.

Затем в нашей мутации мы указываем тип входных данных в свойстве args.