Improved Upgrade guide

This commit is contained in:
Syrus Akbary 2017-07-23 20:12:54 -07:00
parent 907a3d9915
commit 66468e3ea5

View File

@ -1,92 +1,119 @@
# v2.0 Upgrade Guide # v2.0 Upgrade Guide
* `ObjectType`, `Interface`, `InputObjectType`, `Scalar` and `Enum` implementations `ObjectType`, `Interface`, `InputObjectType`, `Scalar` and `Enum` implementations
have been quite simplified, without the need of define a explicit Metaclass. have been quite simplified, without the need to define a explicit Metaclass for each subtype.
The metaclasses threfore are now deleted as are no longer necessary, if your code was depending
on this internal metaclass for creating custom attrs, please see an [example of how to do it now in 2.0](https://github.com/graphql-python/graphene/blob/2.0/graphene/tests/issues/test_425.py). It also improves the function resolvers, [simplifying the code](#resolve_only_args) the
developer have to write to use them.
Deprecations:
* [`AbstractType`](#abstracttype-deprecated)
* [`resolve_only_args`](#resolve_only_args)
Breaking changes:
* [`Node Connections`](#node-connections)
New Features!
* [`InputObjectType`](#inputobjecttype)
* [`Meta as Class arguments`](#meta-ass-class-arguments) (_only available for Python 3_)
> The type metaclases are now deleted as are no longer necessary, if your code was depending
> on this strategy for creating custom attrs, see an [example on how to do it in 2.0](https://github.com/graphql-python/graphene/blob/2.0/graphene/tests/issues/test_425.py).
## Deprecations ## Deprecations
### AbstractType deprecated
* AbstractType is deprecated, please use normal inheritance instead. AbstractType is deprecated in graphene 2.0, you can now use normal inheritance instead.
Before: Before:
```python ```python
class CommonFields(AbstractType): class CommonFields(AbstractType):
name = String() name = String()
class Pet(CommonFields, Interface): class Pet(CommonFields, Interface):
pass pass
``` ```
With 2.0: With 2.0:
```python ```python
class CommonFields(object): class CommonFields(object):
name = String() name = String()
class Pet(CommonFields, Interface): class Pet(CommonFields, Interface):
pass pass
``` ```
* Meta options as class arguments (**ONLY PYTHON 3**). ### resolve\_only\_args
Before: `resolve_only_args` is now deprecated in favor of type annotations (using the polyfill `@graphene.annotate` in Python 2).
```python Before:
class Dog(ObjectType):
class Meta:
interfaces = [Pet]
name = String()
```
With 2.0: ```python
class User(ObjectType):
name = String()
@resolve_only_args
def resolve_name(self):
return self.name
```
With 2.0:
```python
class User(ObjectType):
name = String()
# Decorate the resolver with @annotate in Python 2
def resolve_name(self) -> str:
return self.name
```
```python
class Dog(ObjectType, interfaces=[Pet]):
name = String()
```
## Breaking Changes ## Breaking Changes
* Node types no longer have a `Connection` by default. ### Node Connections
In 2.0 and onwoards `Connection`s should be defined explicitly.
Before: Node types no longer have a `Connection` by default.
In 2.0 and onwards `Connection`s should be defined explicitly.
```python Before:
class User(ObjectType):
class Meta:
interfaces = [relay.Node]
name = String()
class Query(ObjectType): ```python
user_connection = relay.ConnectionField(User) class User(ObjectType):
``` class Meta:
interfaces = [relay.Node]
name = String()
With 2.0: class Query(ObjectType):
user_connection = relay.ConnectionField(User)
```
```python With 2.0:
class User(ObjectType):
class Meta:
interfaces = [relay.Node]
name = String()
class UserConnection(relay.Connection): ```python
class Meta: class User(ObjectType):
node = User class Meta:
interfaces = [relay.Node]
name = String()
class Query(ObjectType): class UserConnection(relay.Connection):
user_connection = relay.ConnectionField(UserConnection) class Meta:
``` node = User
class Query(ObjectType):
user_connection = relay.ConnectionField(UserConnection)
```
## New Features ## New Features
### InputObjectType ### InputObjectType
`InputObjectType`s are now a first class citizen in Graphene. If you are using `InputObjectType`, you now can access
That means, if you are using a custom InputObjectType, you can access
it's fields via `getattr` (`my_input.myattr`) when resolving, instead of it's fields via `getattr` (`my_input.myattr`) when resolving, instead of
the classic way `my_input['myattr']`. the classic way `my_input['myattr']`.
@ -95,9 +122,6 @@ And also use custom defined properties on your input class.
Example. Before: Example. Before:
```python ```python
class User(ObjectType):
name = String()
class UserInput(InputObjectType): class UserInput(InputObjectType):
id = ID() id = ID()
@ -117,27 +141,40 @@ class Query(ObjectType):
With 2.0: With 2.0:
```python ```python
class User(ObjectType):
id = ID()
class UserInput(InputObjectType): class UserInput(InputObjectType):
id = ID() id = ID()
@property @property
def is_user_id(self): def is_user_id(self):
return id.startswith('userid_') return self.id.startswith('userid_')
class Query(ObjectType): class Query(ObjectType):
user = graphene.Field(User, id=UserInput()) user = graphene.Field(User, id=UserInput())
@annotate(input=UserInput) # Decorate the resolver with @annotate(input=UserInput) in Python 2
def resolve_user(self, input): def resolve_user(self, input: UserInput) -> User:
if input.is_user_id:
return get_user(input.id)
# You can also do in Python 3:
def resolve_user(self, input: UserInput):
if input.is_user_id: if input.is_user_id:
return get_user(input.id) return get_user(input.id)
``` ```
### Meta as Class arguments
Now you can use the meta options as class arguments (**ONLY PYTHON 3**).
Before:
```python
class Dog(ObjectType):
class Meta:
interfaces = [Pet]
name = String()
```
With 2.0:
```python
class Dog(ObjectType, interfaces=[Pet]):
name = String()
```