graphene/UPGRADE-v1.0.md

195 lines
4.8 KiB
Markdown
Raw Permalink Normal View History

2016-06-10 11:37:08 +03:00
# v1.0 Upgrade Guide
Big changes from v0.10.x to 1.0. While on the surface a lot of this just looks like shuffling around API, the entire codebase has been rewritten to handle some really great use cases and improved performance.
## Backwards Compatibility and Deprecation Warnings
This has been a community project from the start, we need your help making the upgrade as smooth as possible for everybody!
We have done our best to provide backwards compatibility with deprecated APIs.
2016-09-14 06:40:16 +03:00
## Deprecations
* `with_context` is no longer needed. Resolvers now always take the context argument.
2016-09-18 19:06:58 +03:00
Before:
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
```python
def resolve_xxx(self, args, info):
# ...
```
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
With 1.0:
```python
def resolve_xxx(self, args, context, info):
# ...
```
2016-09-14 06:40:16 +03:00
* `ObjectType` and `Interface` no longer accept the `abstract` option in the `Meta`.
2016-09-14 06:40:16 +03:00
Inheriting fields should be now achieved using `AbstractType` inheritance.
2016-09-18 19:06:58 +03:00
Before:
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
```python
class MyBaseQuery(graphene.ObjectType):
my_field = String()
class Meta:
abstract = True
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
class Query(MyBaseQuery):
pass
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
```
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
With 1.0:
```python
class MyBaseQuery(graphene.AbstractType):
my_field = String()
2016-09-14 06:40:16 +03:00
2016-09-18 19:06:58 +03:00
class Query(MyBaseQuery, graphene.ObjectType):
pass
```
2016-09-14 06:40:16 +03:00
* The `type_name` option in the Meta in types is now `name`
2016-09-18 23:14:52 +03:00
* Type references no longer work with strings, but with functions.
Before:
```python
class Query(graphene.ObjectType):
user = graphene.Field('User')
users = graphene.List('User')
```
With 1.0:
```python
class Query(graphene.ObjectType):
user = graphene.Field(lambda: User)
users = graphene.List(lambda: User)
```
2016-09-14 06:40:16 +03:00
2016-09-15 07:17:43 +03:00
## Schema
Schemas in graphene `1.0` are `Immutable`, that means that once you create a `graphene.Schema` any
change in their attributes will not have any effect.
The `name` argument is removed from the Schema.
The arguments `executor` and `middlewares` are also removed from the `Schema` definition.
You can still use them, but by calling explicitly in the `execute` method in `graphql`.
2016-09-15 07:17:43 +03:00
```python
# Old way
schema = graphene.Schema(name='My Schema')
schema.query = Query
schema.mutation = Mutation
# New way
schema = graphene.Schema(
query=Query,
mutation=Mutation
)
```
2016-06-10 11:37:08 +03:00
## Interfaces
2016-08-15 01:45:41 +03:00
For implementing an Interface in a ObjectType, you have to it onto `Meta.interfaces`.
2016-06-10 11:37:08 +03:00
Like:
```python
from graphene import Interface, ObjectType, String
class Character(Interface):
name = String()
2016-08-15 01:45:41 +03:00
class Human(Character): # Old way, Human will still be an Interface
2016-06-10 11:37:08 +03:00
pass
2016-08-15 01:45:41 +03:00
class Droid(ObjectType): # New way, you have to specify the ObjectType
class Meta:
interfaces = (Character, )
2016-06-10 11:37:08 +03:00
```
## Mutations
Mutation fields have changed the way of usage, before if you have the mutation `MyMutation` you
only have to reference with `graphene.Field(MyMutation)` now it's simply `MyMutation.Field()`
Example:
```python
from graphene import ObjectType, Mutation, String
class ReverseString(Mutation):
class Input:
2016-06-10 11:43:06 +03:00
input = String(required=True)
2016-06-10 11:37:08 +03:00
reversed = String()
2016-06-10 11:43:06 +03:00
def mutate(self, args, context, info):
reversed = args.get('input')[::-1]
return ReverseString(reversed=reversed)
2016-06-10 11:37:08 +03:00
class Query(ObjectType):
2016-08-15 01:45:41 +03:00
reverse_string = graphene.Field(ReverseString) # Old way, will not include the mutation arguments by default
2016-06-10 11:37:08 +03:00
reverse_string = ReverseString.Field()
```
## Nodes
Apart of implementing as showed in the previous section, for use the node field you have to
specify the node Type.
Example:
```python
from graphene import ObjectType, relay
class Query(ObjectType):
2016-08-15 01:45:41 +03:00
node = relay.NodeField() # Old way, NodeField no longer exists. Use Node.Field
2016-06-10 11:37:08 +03:00
node = relay.Node.Field() # New way
2016-08-07 05:56:43 +03:00
```
Also, if wanted to create an `ObjectType` that implements `Node`, you have to do it
explicity.
## Django
The Django integration with Graphene now have an independent package: `graphene-django`.
For installing, you have to replace the old `graphene[django]` with `graphene-django`.
2016-08-15 01:45:41 +03:00
* As the package is now independent, you have to import now from `graphene_django`.
* **DjangoNode no longer exists**, please use `relay.Node` instead:
2016-08-07 05:56:43 +03:00
2016-09-18 19:06:58 +03:00
```python
from graphene.relay import Node
from graphene_django import DjangoObjectType
2016-08-07 05:56:43 +03:00
2016-09-18 19:06:58 +03:00
class Droid(DjangoObjectType):
class Meta:
interfaces = (Node, )
```
2016-08-07 05:56:43 +03:00
## SQLAlchemy
The SQLAlchemy integration with Graphene now have an independent package: `graphene-sqlalchemy`.
For installing, you have to replace the old `graphene[sqlalchemy]` with `graphene-sqlalchemy`.
2016-08-15 01:45:41 +03:00
* As the package is now independent, you have to import now from `graphene_sqlalchemy`.
* **SQLAlchemyNode no longer exists**, please use `relay.Node` instead:
2016-08-07 05:56:43 +03:00
2016-09-18 19:06:58 +03:00
```python
from graphene.relay import Node
from graphene_sqlalchemy import SQLAlchemyObjectType
2016-08-15 01:45:41 +03:00
2016-09-18 19:06:58 +03:00
class Droid(SQLAlchemyObjectType):
class Meta:
interfaces = (Node, )
```