payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
22.87k stars 1.41k forks source link

GraphQL doesn't respect `draft` argument #6813

Open wkentdag opened 2 months ago

wkentdag commented 2 months ago

Link to reproduction

No response

Describe the Bug

Passing draft: false to a versioned GraphQL list type has no effect. The only way to filter out drafts is to use a where clause on _status.

query {
  # ❌ incorrectly returns drafts
  shouldntReturnDrafts: Posts(draft: false) {
    docs {
      _status
    }
  }

  # ✅ doesnt return drafts
  doesntReturnDrafts: Posts(where: {
    _status: {
      equals: published
    }
  }) {
    docs {
      _status
    }
  }
}

I noticed this bug in the process of isolating #6800, and I'm wondering if they might be related; if the graphQL query doesn't match the underlying db query, it could cause "invalid" return values resulting in the type of Cannot return null for non-nullable field X errors that I detailed in the other ticket.

To Reproduce

  1. Make a new draft post in the public demo
  2. Run the above query in the playground or with curl
  3. Note that shouldntReturnDrafts does indeed return your draft document
`curl 'https://demo.payloadcms.com/api/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: https://demo.payloadcms.com' --data-binary '{"query":"# Write your queryquer or mutation here\nquery {\n  shouldntReturnDrafts: Posts(draft: false) {\n    docs {\n      _status\n    }\n  }\n  \n  doesntReturnDrafts: Posts(where: {\n    _status: {\n      equals: published\n    }\n  }) {\n    docs {\n      _status\n    }\n  }\n}"}' --compressed`

Screen Shot 2024-06-17 at 10 03 09 AM

Payload Version

2.20.0

Adapters and Plugins

No response

JarrodMFlesch commented 2 months ago

@wkentdag I think this might be working as intended. When you query with draft: true, really that is getting the most recent version for each document. The most recent one could be in state published or draft. The docs touch on this a little bit: https://payloadcms.com/docs/versions/drafts#reading-drafts-vs-published-documents

Can you confirm that this is what you are experiencing?

wkentdag commented 2 months ago

@JarrodMFlesch my question is why drafts are still returned when you specify draft: false in the query. Per the docs you linked:

If draft is set to true while reading a document, Payload will automatically replace returned document(s) with their newest drafts if any newer drafts are available.

If you simply fetch your created document using a find or findByID operation, your published document will be returned and the drafts will be ignored.

I read that as "the result set will not include drafts unless you explicitly specify draft: true". Am I misinterpreting something? Because that does not match what I'm seeing, where drafts are always returned unless I pass in a full where clause to omit them.

I should also clarify that I'm talking about new drafts (ie, no published version). Toggling the draft arg on/off does work as expected for changed documents (published version w/ some draft updates). However, it seems like new draft documents are slipping through the cracks.