Reputation: 73
This is an example of a document I am trying to retrieve:
{
"ref": Ref(Collection("Word"), "270608756095582738"),
"ts": 1594331477980000,
"data": {
"word": "ablatitious",
"letters": [
{
"letter": "a",
"occurrence": 2
},
{
"letter": "b",
"occurrence": 1
},
{
"letter": "l",
"occurrence": 1
},
{
"letter": "t",
"occurrence": 2
},
{
"letter": "i",
"occurrence": 2
},
{
"letter": "o",
"occurrence": 1
},
{
"letter": "u",
"occurrence": 1
},
{
"letter": "s",
"occurrence": 1
}
],
"length": 11
}
}
This is my schema
type Letter @embedded {
letter: String! @unique
occurrence: Int!
}
type Word {
word: String! @unique
letters: [Letter]!
length: Int!
}
input LetterInput {
letter: String!
occurrence: Int!
}
type Query {
Word(length: Int!): Word
WordByLetters(letters: [LetterInput!]): Word
}
This is the error I get when I attempt to update my schema with this schema:
Schema does not pass validation. Violations:
Type mismatch: field 'letters' defined at object 'Word' has type 'Letter'. (line 19, column 17):
WordByLetters(letters: LetterInput): Word
^
If I switch the type LetterInput
to Letter
in the WordByLetters
query type, I get this error
Type 'Letter' is not an input type type. (line 19, column 26):
WordByLetters(letters: Letter): Word
^
So, clearly, I need to use an input type, which makes sense. What does not make sense is the first of the two errors. Can somebody please explain why?
Upvotes: 0
Views: 218
Reputation: 1822
FaunaDB dev advocate here.
I'm not an expert on our GraphQL (I'll poke one of the experts if you are still stuck). When you define queries like that in FaunaDB's GraphQL it will try to match the attribute (letters: Letter) to one of the attributes in the return type (Word).
Since that return type is Word
type Word {
word: String! @unique
letters: [Letter]!
length: Int!
}
it's logical that you try to place Letter there. However if I'm not mistaking it should be the more exact which meant it has to be [ Letter ]. However, since Letter is a type, you will have to present an ID instead of the actual Letter object. You might try to define:
WordByLetters(letters: [ ID ] ): Word
instead but I'm honestly not sure whether you can place arrays in the arguments. And since what you need is actually this:
WordByLetters(letters: ID ): Word
which we don't really support atm if I'm not mistaking. What you could do however is to not define the letters as embedded, connect to the correct letters (instead of embedding them each time). You would then also change your schema slightly to have a many to many relation:
type Letter {
letter: String! @unique
occurrence: Int!
words: [ Word! ]!
}
You could predefine all letters to get easy access to the IDs of the letters. If you do that (I don't think this would work with embedded but I'm not 100% certain) you could find the words via the letters:
type Query {
findLetterByID(id: ID!): Letter
}
which is a query that is already defined by FaunaDB (at least if Letters would not be embedded, I barely worked with embedded myself, hence I'm not sure about some of the embedded things). Or you could define:
type Query {
findLetter(letter: String!): Letter
}
And then you could get the words via:
query GetWordsByLetter {
findLetter(_size: 6, letter: "a"){
data {
words {
...
}
}
}
}
If that doesn't work for you, you probably want to specify a resolver on the query which will generate a User Defined Function for you. This requires you to dive into FQL since UDFs are specified in FQL but it will unlock much more possibilities.
(resolver docs: https://docs.fauna.com/fauna/current/api/graphql/directives/d_resolver)
Upvotes: 1