-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
m.kindritskiy
committed
Jul 29, 2023
1 parent
7dad476
commit e1eb981
Showing
4 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ User's Guide | |
asyncio | ||
graphql | ||
protobuf | ||
interfaces | ||
unions | ||
directives | ||
federation | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
Interfaces | ||
========== | ||
|
||
.. _interfaces-doc: | ||
|
||
Interfaces are a special types that other types can implement. | ||
|
||
Interfaces are useful when you want to define a common set of fields. | ||
|
||
In graphql you can use interfaces types like this: | ||
|
||
.. code-block:: | ||
interface Media { | ||
id: ID! | ||
duration: String! | ||
} | ||
type Audio implements Media { | ||
id: ID! | ||
duration: Int! | ||
album: String! | ||
} | ||
type Video implements Media { | ||
id: ID! | ||
duration: String! | ||
thumbnailUrl: String! | ||
} | ||
type Query { | ||
search(text: String!): [Media!]! | ||
} | ||
In `hiku` you can define interface types like this: | ||
|
||
.. code-block:: python | ||
from hiku.graph import Field, Graph, Link, Node, Root, Interface | ||
from hiku.types import ID, Integer, String, TypeRef, Sequence, Optional, InterfaceRef | ||
from hiku.utils import empty_field | ||
def search_resolver(): | ||
return [ | ||
(1, TypeRef['Audio']), | ||
(2, TypeRef['Video']), | ||
] | ||
interfaces = [ | ||
Interface('Media', [ | ||
Field('id', ID, empty_field), | ||
Field('duration', String, empty_field), | ||
]), | ||
] | ||
GRAPH = Graph([ | ||
Node('Audio', [ | ||
Field('id', ID, audio_fields_resolver), | ||
Field('duration', String, audio_fields_resolver), | ||
Field('album', String, audio_fields_resolver), | ||
], implements=['Media']), | ||
Node('Video', [ | ||
Field('id', ID, video_fields_resolver), | ||
Field('duration', String, video_fields_resolver), | ||
Field('thumbnailUrl', String, video_fields_resolver), | ||
], implements=['Media']), | ||
Root([ | ||
Link('search', Sequence(UnionRef['Media']), search_resolver, requires=None), | ||
]), | ||
], interfaces=interfaces) | ||
Lets look at the example above: | ||
|
||
- `Interface` type is defined with a name and a list of fields that any implementation type must contain. | ||
- `Audio` and `Video` types implement `Media` interface - they have `id` and `duration` field because `Media` interface declares them, and in adition to those shared fields each type has its own fields. | ||
- `Link` type is defined with a return type of `Sequence[InterfaceRef['Media']]` | ||
- `search_resolver` returns a list of tuples with an id as a first tuple element and type as a second tuple element | ||
- note that interface fields does need to have a resolver function, but currently this function is not used by hiku engine so you can pass `empty_field` as a resolver function (it may change in the future) | ||
|
||
.. note:: | ||
|
||
`InterfaceRef` is a special type that is used to reference interface types. It is used in the example above to define | ||
the return type of the `search` link. `TypeRef` will not work in this case. | ||
|
||
Now lets look at the query: | ||
|
||
.. code-block:: python | ||
query { | ||
search(text: "test") { | ||
__typename | ||
id | ||
duration | ||
... on Audio { | ||
album | ||
} | ||
... on Video { | ||
thumbnailUrl | ||
} | ||
} | ||
} | ||
As a result of the query above you will get a list of objects with `__typename`, `id` and `duration` fields and fields that are specific | ||
to the type of the object. | ||
|
||
.. code-block:: | ||
[ | ||
{ | ||
'__typename': 'Audio', | ||
'id': 1, | ||
'duration': '1:20', | ||
'album': 'Cool album', | ||
}, | ||
{ | ||
'__typename': 'Video', | ||
'id': 2, | ||
'duration': '1:40', | ||
'thumbnailUrl': 'http://example.com/thumbnail.jpg', | ||
}, | ||
] | ||
Type narrowing | ||
-------------- | ||
|
||
Unlike other graphql implementations `hiku` supports type narrowing without | ||
`__resolveType` function. It is possible because `hiku` knows all possible types | ||
at the link resolution time. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters