Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Graphene

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 Graphene

Extending the limits of GraphQL

Avatar for Syrus Akbary

Syrus Akbary

October 25, 2017
Tweet

More Decks by Syrus Akbary

Other Decks in Technology

Transcript

  1. @syrusakbary Graphene.tools Who am I? • Syrus Akbary, CTO @

    .com • Builder @ Graphene Ecosystem.
  2. @syrusakbary Graphene.tools Overview • Graphene is now two years old

    • Most starred GraphQL framework - 2500★ • Used in 100+ companies in production
 
 

  3. @syrusakbary Graphene.tools Continuous Growth 0 15000 30000 45000 60000 Jan

    Mar May Jul Sept Non-defined version Python2 Python3 Python3 > 50% installs!
  4. @syrusakbary Graphene.tools • Better Resolution API • Simplified codebase, easier

    to contribute • Full advantage of Python 3 (async iterators, class definitions) • Subscriptions! Graphene-Python 2.0
  5. @syrusakbary Graphene.tools Better Resolution API hello(name: String): String def resolve_hello(root,

    args, context, info): return args.get(‘name’) Graphene 1.X def resolve_hello(root, info, name): return name Graphene 2.X
  6. @syrusakbary Graphene.tools Better Resolution API hello(name: String): String def resolve_hello(root,

    args, context, info): return args.get(‘name’) Graphene 1.X def resolve_hello(root, info, name): return name Graphene 2.X
  7. @syrusakbary Graphene.tools Subscriptions from graphql_aiows import AIOHttpWebsocketServer websocket_server = AIOHttpWebsocketServer(schema)

    def graphql_websocket(request): return websocket_server.handle(request) Websocket server class Subscription(graphene.ObjectType): count_to = graphene.Int(max=graphene.Int()) async def resolve_count_to(root, info, max=10): for i in range(max): yield i await asyncio.sleep(1.0) # Sleep 1 sec Subscription type Thanks to async iterators
 in Python 3.6
  8. @syrusakbary Graphene.tools Graphene-JS Goals • Easier to read / less

    code for creating your Schema • Integration with external data sources, starting with Sequelize ORM!
  9. @syrusakbary Graphene.tools Frameworks Comparison type Query { hello(name: String!): String!

    } class Query extends ObjectType { static fields = { hello: new Str({args: {name: new Str()}}), todayIs: new Str(), } hello = ({name}) => `hello ${name}`, todayIs = () => `Wednesday!` } var Query = GraphQLObjectType({ name: Query, fields: { hello: { type: GraphQLString, args: { name: GraphQLString }, resolver: ({name}) => `hello ${name}` }, todayIs: { type: GraphQLString, resolver: () => `Wednesday!` }, } } GraphQL-JS
  10. @syrusakbary Graphene.tools interface UserBase { id: ID name: String }

    type AnonymousUser extends UserBase type RegisteredUser extends UserBase class UserBase extends Interface { static fields = { id: new ID(), name: new String(), } } class AnonymousUser extends ObjectType { static interfaces = [UserBase] } class RegisteredUser extends ObjectType { static interfaces = [UserBase] } var UserBase = GraphQLInterfaceType({ name: UserBase, fields: { id: { type: GraphQLId, }, name: { type: GraphQLString, }, } } var AnonymousUser = GraphQLObjectType({ name: Query, interfaces: [UserBase]. fields: { id: { type: GraphQLId, }, name: { type: GraphQLString, }, } } var RegisteredUser = GraphQLObjectType({ name: Query, interfaces: [UserBase]. fields: { id: { type: GraphQLId, }, name: { type: GraphQLString, }, } } GraphQL-JS
  11. @syrusakbary Graphene.tools ❤ Templates • I’ve been always very interested

    in how template engines work internally. Launched PyJade 6 years ago. • Since then, I’ve been experimenting with a lot of different template engines, from Python to JS.
  12. @syrusakbary Graphene.tools Template Engine Analysis render(template, { "user": { "is_authenticated":

    True, "username": "Peter" } }) Hello, Peter. def render_template(context): value = "" if user.is_authenticated: Value += "Hello, " value += str(user.username) return value Precompile to Native code Execute render function Hello, Peter. Jinja2 {% if user.is_authenticated %} Hello, {{ user.username }}. {% endif %} Render in Runtime {% if user.is_authenticated %} Hello, {{ user.username }}. {% endif %} Django
  13. @syrusakbary Graphene.tools GraphQL Engine Analysis { hello(name: $username) } GraphQL-*

    graphql(query, variables={ "username": "Peter" }) {"hello": "Peter"} def execute_query(root, variables, …): ast, query_type, hello_field, info = … result = {} name = variables["username"] result["hello"] = hello_field.resolver( root, info, name=name ) return result Precompile to Native code Execute query function Quiver { hello(name: $username) } Query in Runtime {"hello": "Peter"}
  14. @syrusakbary Graphene.tools Some benchmarks Simple Query Highly Nested Query Complex

    Query with Fragments (lower is better) 0 ms 400 ms 800 ms 1,200 ms 1,600 ms GraphQL core Quiver
  15. @syrusakbary Graphene.tools More benchmarks • +300.000 resolutions / sec (Python

    - CPython) • +1.000.000 resolutions / sec (Python - pypy)
  16. @syrusakbary Graphene.tools Same principles, multiple languages • This strategy could

    be specially beneficial in interpreted languages. • 5-10x performance: CPython, Ruby • 2-3x performance in JIT-enhanced backends: Pypy, V8, Spidermonkey, Hack …
  17. @syrusakbary Graphene.tools Thanks • Graphene collaborators: • Patrick Armino: DRF

    integration • Jacob Foster: Graphene-Django • Devin Fee: Graphene-AIOHttp • Performance & Optimization feedback: • Marc Tamlyn • Klemen Sever • Side projects: • Nick Schrock: GraphScale • Predrag Gruevski - Kensho technologies: GraphQL-compiler