Skip to content

Commit

Permalink
add docs for interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
m.kindritskiy committed Jul 29, 2023
1 parent 7dad476 commit e1eb981
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/changelog/changes_07.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Changes in 0.7
- Added support for custom schema directives :ref:`Check directives documentation <directives-doc>`
- Added `ID` type.
- Added support for unions :ref:`Check unions documentation <unions-doc>`
- Added support for interfaces :ref:`Check interfaces documentation <interfaces-doc>`

Backward-incompatible changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ User's Guide
asyncio
graphql
protobuf
interfaces
unions
directives
federation
Expand Down
129 changes: 129 additions & 0 deletions docs/interfaces.rst
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.
2 changes: 2 additions & 0 deletions docs/unions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Unions

Union types are special types used to represent a value that could be one of types.

.. note:: Unlike interfaces, unions do not define any common fields between types.

In graphql you can use union types like this:

.. code-block::
Expand Down

0 comments on commit e1eb981

Please sign in to comment.