简体   繁体   中英

When updating a record in FaunaDB, how do I update one field without passing in every field and subobject?

Perhaps I haven't grasped GraphQL yet, but I want to update a complex record in the DB. I'm having trouble finding docs that explain this, which doesn't use a trivial example. I am using FaunaDB and trying to test things in the GraphQL playground before implementing it in JS.

Here is an an example of my schema:

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
}

I want to update a field on the event: sentConfirmation , that's it.

I know the event Id and what I want to update the Boolean value to.

Is there a way to write a mutation to just pass in an ID and the updated Boolean value and change that single value, or do I need to literally pass in the entire object and all it's sub objects with just that one top level field updated?

This should be possible by calling the autogenerated partialUpdate mutation. You might have not noticed it, since this is currently only available as a Schema Preview feature.

This means essentially that in order to enable it, you will need to add the following header to your HTTP Request:

X-Schema-Preview: partial-update-mutation

Note that since this Schema Preview feature adds a new autogenerated mutation, you will have to add this header when executing a GraphQL operation (ie, sending request against the /graphql endpoint), and not when importing the schema (ie, sending a request agains the /import endpoint). The reason is basically that all of the autogenerated queries and mutations are derived at runtime , and not when the schema is imported.

Now, if you have added the header as mentioned above, when calling some introspection query for reading the schema back (like the GraphQL Playground does for instance), you should notice there's a new mutation field and a new input object:

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
}

Since all of the fields are optional for this new input object, you should be able now to update just the sentConfirmation field:

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

All of the fields which are not included in the mutation will remain unaffected.

Establishing a parallel with FQL, this means that GraphQL's update mutation will act as FQL's Replace function, and GraphQL's partialUpdate mutation as FQL's Update function.

my first reflection was also: "have you tried it?" but I immediately assumed you did. Your problem is caused by the fact that all of your attributes are mandatory (as you specify with the exclamation ( ! ) marks behind the attributes). These fields therefore are also checked on the update. Arguably, that might be unnecessary and I'll ask my colleagues whether we might not want to change that.

You can in each case 'solve' your problem by removing the required fields. In that case you can perfectly do:

# 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}

}

followed by:

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

and your document's boolean 'completed' field will be updated.

在此处输入图像描述

Usually, I create two different input types. In your case it would be createEventInput and updateEventInput .

In the createEventInput all or most fields are mandatory while in the updateEventInput you could have more fields optional. But you need to be careful not to end up updating you record with empty values for fields that are actually mandatory for your internal business logic.

createEvent(data: createEventInput) {... }

updateEvent(data: updateEventInput) {... }

FaunaDB creates similar input types for both create* and update* mutations. But you can create you own input types as stated in the FaunaDB docs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM