При обновлении записи в GraphQL, как мне обновить одно поле, не передавая каждое поле и подобъект?

Возможно, я еще не разобрался в GraphQL, но хочу обновить сложную запись в БД. У меня проблемы с поиском документов, объясняющих это, в которых нет тривиального примера. Я использую FaunaDB и пытаюсь протестировать вещи на игровой площадке GraphQL, прежде чем реализовывать ее в JS.

Вот пример моей схемы:

type Event {
    name: String!
    email: String!
    eventName: String!
    location: String
    guests: [Guest!]!
    note: String!
    confirmed: Boolean!
    completed: Boolean!
    dateTimeStart: Time
    dateTimeEnd: Time
    sentConfirmation: Boolean!
}

type Guest @embedded {
    email: String!
    rsvp: Boolean
    results: SurveyAnswers
}

type SurveyAnswers @embedded {
    ~ 12 various fields
}

Я хочу обновить поле события: sentConfirmation, вот и все.

Я знаю идентификатор события и то, что я хочу обновить логическое значение.

Есть ли способ написать мутацию, чтобы просто передать идентификатор и обновленное логическое значение и изменить это единственное значение, или мне нужно буквально передать весь объект и все его подобъекты с обновленным только этим одним полем верхнего уровня?

3 ответа

Решение

Это должно быть возможно, вызвав автоматически созданный partialUpdateмутация. Возможно, вы этого не заметили, так как в настоящее время это доступно только как функция предварительного просмотра схемы.

По сути, это означает, что для его включения вам нужно будет добавить следующий заголовок в свой HTTP-запрос:

X-Schema-Preview: partial-update-mutation

Обратите внимание, что, поскольку эта функция схемы Preview добавляет новую сгенерированную мутацию, вы должны добавить этот заголовок при выполнении операции GraphQL (то есть, послав запрос по отношению к / graphql конечной точки), а не при импорте схемы (то есть, послав запрос Agains импорт / конечная точка). Причина в том, что все автоматически сгенерированные запросы и мутации производятся во время выполнения, а не при импорте схемы.

Теперь, если вы добавили заголовок, как упоминалось выше, при вызове некоторого запроса самоанализа для чтения схемы обратно (как, например, GraphQL Playground), вы должны заметить, что есть новое поле мутации и новый объект ввода:

input PartialUpdateEventInput {
  name: String
  email: String
  eventName: String
  location: String
  guests: [PartialUpdateGuestInput!]
  note: String
  confirmed: Boolean
  completed: Boolean
  dateTimeStart: Time
  dateTimeEnd: Time
  sentConfirmation: Boolean
}

type Mutation {
  partialUpdateEvent(id: ID!, data: PartialUpdateEventInput!): Event
}

Поскольку все поля для этого нового входного объекта являются необязательными, теперь вы сможете обновить только sentConfirmation поле:

mutation PartialUpdate {
  partialUpdateEvent(id: "269434161519919634", data: {
    sentConfirmation: true
  }) {
    _id
  }
}

Все поля, не включенные в мутацию, останутся без изменений.

Установление параллели с FQL означает, что GraphQL update мутация будет действовать как FQL Replace функция и GraphQL partialUpdateмутации как функция обновления FQL.

Моей первой мыслью было также: "Вы пробовали это?" но я сразу предположил, что это так. Ваша проблема вызвана тем, что все ваши атрибуты являются обязательными (как вы указываете восклицательными знаками (!) После атрибутов). Поэтому эти поля также проверяются при обновлении. Возможно, в этом нет необходимости, и я спрошу своих коллег, не хотим ли мы это изменить.

В каждом случае вы можете "решить" свою проблему, удалив обязательные поля. В этом случае вы отлично можете:

# Write your query or mutation here
mutation test {
  createEvent(data: {
    name: "Test",
    email: "test@test.com",
    eventName: "lala"
    note: "I am a note",
    confirmed:true,
    completed:true,
    sentConfirmation: false
  })
  {_id}

}

с последующим:

# Write your query or mutation here
mutation test {
  updateEvent(id: "269430330059915782", data:{
    completed:false
  })
  {_id}
}

и в вашем документе будет обновлено логическое поле "завершено".

Обычно я создаю два разных типа ввода. В вашем случае это было быcreateEventInput а также updateEventInput.

в createEventInput все или большинство полей являются обязательными, если в updateEventInputу вас может быть больше полей по желанию. Но вы должны быть осторожны, чтобы не обновить вашу запись пустыми значениями для полей, которые на самом деле являются обязательными для вашей внутренней бизнес-логики.

createEvent(data: createEventInput) {...}

updateEvent(данные: updateEventInput) {...}

FaunaDB создает похожие типы ввода для обоих create* а также update*мутации. Но вы можете создавать собственные типы ввода, как указано в документации FaunaDB.

Другие вопросы по тегам