2017-07-12 09:52:24 +03:00
# v2.0 Upgrade Guide
2017-07-12 06:33:03 +03:00
2017-07-12 09:07:20 +03:00
* `ObjectType` , `Interface` , `InputObjectType` , `Scalar` and `Enum` implementations
have been quite simplified, without the need of define a explicit Metaclass.
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/master/graphene/tests/issues/test_425_graphene2.py ).
2017-07-12 06:33:03 +03:00
## Deprecations
* AbstractType is deprecated, please use normal inheritance instead.
Before:
```python
class CommonFields(AbstractType):
name = String()
class Pet(CommonFields, Interface):
pass
```
With 2.0:
2017-07-12 08:52:38 +03:00
2017-07-12 06:33:03 +03:00
```python
class CommonFields(object):
name = String()
class Pet(CommonFields, Interface):
pass
```
2017-07-12 08:52:38 +03:00
* 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()
```
2017-07-13 07:53:35 +03:00
## Breaking Changes
* Node types no longer have a `Connection` by default.
In 2.0 and onwoards `Connection` s should be defined explicitly.
Before:
```python
class User(ObjectType):
class Meta:
interfaces = [relay.Node]
name = String()
class Query(ObjectType):
user_connection = relay.ConnectionField(User)
```
With 2.0:
```python
class User(ObjectType):
class Meta:
interfaces = [relay.Node]
name = String()
class UserConnection(relay.Connection):
class Meta:
node = User
class Query(ObjectType):
user_connection = relay.ConnectionField(UserConnection)
```
2017-07-24 04:57:17 +03:00
## New Features
### InputObjectType
`InputObjectType` s are now a first class citizen in Graphene.
That means, if you are using a custom InputObjectType, you can access
it's fields via `getattr` (`my_input.myattr`) when resolving, instead of
the classic way `my_input['myattr']` .
And also use custom defined properties on your input class.
Example. Before:
```python
class User(ObjectType):
name = String()
class UserInput(InputObjectType):
id = ID()
def is_user_id(id):
return id.startswith('userid_')
class Query(ObjectType):
user = graphene.Field(User, id=UserInput())
@resolve_only_args
def resolve_user(self, input):
user_id = input.get('id')
if is_user_id(user_id):
return get_user(user_id)
```
With 2.0:
```python
class User(ObjectType):
id = ID()
class UserInput(InputObjectType):
id = ID()
@property
def is_user_id(self):
return id.startswith('userid_')
class Query(ObjectType):
user = graphene.Field(User, id=UserInput())
@annotate (input=UserInput)
def resolve_user(self, input):
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:
return get_user(input.id)
```