Pisząc lib dla Graphql w JavaScript, natknąłem się na ciekawe zachowanie. Udało mi się to izolować w bardzo prostym przykładzie. Weźmy ten fragment serwera:


    const { ApolloServer, gql } = require("apollo-server")

    const typeDefs = gql`
      type Book {
        resolveItSelf: String
      }

      type Query {
        book: Book
      }
    `

    const resolvers = {
      Query: {
        book: () => {
          return null // same behavior with undefined here
        }
      },
      Book: {
        resolveItSelf: () => "resolveItSelf"
      }
    }

    const server = new ApolloServer({ typeDefs, resolvers })

    server.listen().then(({ url }) => {
      console.log(`🚀  Server ready at ${url}`)
    })

Jeśli zapytamy ten serwer z następującym zapytaniem:

    {
      book {
        resolveItSelf   
      }
    }

Otrzymujemy ten wynik:

{
  "data": {
    "book": null
  }
}

Spodziewałem się więc wykonawcę graficznego, aby spróbować rozwiązać pole "resollutself" (które mają swój własny resolver), nawet jeśli rezoler książki zwrócił null.

Sposób, aby uzyskać zachowanie, oczekuję, że nieco zmienić resolver książki:

const resolvers = {
  Query: {
    book: () => {
      return {} // empty object instead of null/undefined
    }
  },
  Book: {
    resolveItSelf: () => "resolveItSelf"
  }
}

Potem otrzymujemy ten wynik:

{
  "data": {
    "book": {
      "resolveItSelf": "resolveItSelf"
    }
  }
}

Pole jest rozwiązane, nawet jeśli rodzic jest pusty!

Więc moje pytanie brzmi, dlaczego executor Graphql-JS przestaje próbować rozwiązać pola, jeśli resolver Resolver powróci dzięki Null / Undefined, nawet jeśli żądane pola można rozwiązać na własną rękę? (Czy w projekcie znajduje się sekcja?)

0
theJiBz 3 styczeń 2020, 19:03

1 odpowiedź

Najlepsza odpowiedź

W Graphql, Null reprezentuje brak wartości. Jeśli pole rozwiarcza się do NULL, nie ma sensu, aby nazwać "Dziecko" resolakery pola ", które mają być wywołane, ponieważ tak nie zostaną zwrócone w odpowiedzi.

Z sekcji ukończenia wartości Spec (Kopalnia nacisk ):

  1. Jeśli fieldtype jest typem null:
    za. Niech Innertype będzie wewnętrznym typem Fieldtype.
    b. Niech ukończona będzie wynikiem połączenia kompletnej (innertype, pola, wynik, zmienneValues).
    do. Jeśli ukończony jest null, wyrzuć błąd pola.
    re. Zwróć wypełniony.
  2. , jeśli wynik jest null (lub inna wartość wewnętrzna podobna do nulla, taka jak undefined lub NAN), zwraca wartość null.
  3. jeśli Fieldtype jest typem listy:
    za. Jeśli wynik nie jest zbiorem wartości, rzuć błąd pola.
    b. Niech Innertype będzie wewnętrznym typem Fieldtype.
    do. Zwróć listę, w której każdy element listy jest wynikiem wywołującego kompletnego (innertype, pól, poznania, zmiennych przekazów), w którym poznawane jest każdy element.
  4. IF Fieldtype jest skalarnym lub wyliczonym typem:
    za. Zwróć wynik wyniku "mięśni", zapewniając, że jest to wartość prawna Fieldtype, inaczej NULL.
  5. Jeśli Fieldtype jest obiektem, interfejsem lub typem Unii:
    za. Jeśli fieldtype jest typem obiektu.
    ja. Niech Objecttype Be Fieldtype.
    b. W przeciwnym razie jeśli FieldType jest interfejsem lub typem Unii.
    ja. Niech ObjectTytpe będzie Resolveaebracttype (FieldType, wynik).
    do. Pozwól, aby subseletionset był wynikiem dzwonienia Mergeselalicesetsets (pól).
    re. Zwróć wynik oceny EXECTELECECECTECTETET (subseletionset, obladtype, wynik, różnorodne przekazy) normalnie (umożliwiające równolegle).

Innymi słowy, nawet jeśli typ pola jest obiektem (dlatego ma zestaw wyboru pola, które można również rozwiązać), jeśli rozwiązuje się do NULL, nie ma dalszego wykonania na tej ścieżce.

0
Daniel Rearden 3 styczeń 2020, 20:09