Graphene

 Graphene

Extending the limits of GraphQL

Cf18e42df2acc7a1fc1700bcd8e76487?s=128

Syrus Akbary

October 25, 2017
Tweet

Transcript

  1. Graphene Extending the limits of GraphQL

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

    .com • Builder @ Graphene Ecosystem.
  3. @syrusakbary Graphene.tools Graphene Python

  4. @syrusakbary Graphene.tools Overview • Graphene is now two years old

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

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

    Mar May Jul Sept Non-defined version Python2 Python3 Python3 > 50% installs!
  6. @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
  7. @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
  8. @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
  9. Subscriptions

  10. @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
  11. @syrusakbary Graphene.tools Subscriptions Demo Code available at: https://github.com/graphql-python/graphql-ws

  12. @syrusakbary Graphene.tools MAJOR PROJECT ANNOUNCEMENT!

  13. The most popular GraphQL framework
 ….now in JS! Graphene JS

  14. @syrusakbary Graphene.tools Graphene-JS Goals • Easier to read / less

    code for creating your Schema • Integration with external data sources, starting with Sequelize ORM!
  15. @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
  16. @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
  17. @syrusakbary Graphene.tools Graphene-JS.org

  18. @syrusakbary Graphene.tools MAJOR PROJECT ANNOUNCEMENT!

  19. Storytime

  20. @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.
  21. @syrusakbary Graphene.tools Two Kinds of Templates • The ones that

    are fast • …the ones that are not
  22. @syrusakbary Graphene.tools Speed Time to render (lower is better) 0

    ms 25 ms 50 ms 75 ms 100 ms Django Jinja2
  23. @syrusakbary Graphene.tools But… why?

  24. @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
  25. @syrusakbary Graphene.tools Can we use this strategy in GraphQL engines?

  26. @syrusakbary Graphene.tools (short answer) 
 YES

  27. Next Generation GraphQL Engine Quiver

  28. @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"}
  29. 0
 overhead
 from the framework

  30. @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
  31. @syrusakbary Graphene.tools More benchmarks • +300.000 resolutions / sec (Python

    - CPython) • +1.000.000 resolutions / sec (Python - pypy)
  32. @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 …
  33. @syrusakbary Graphene.tools Available in every major language • Python •

    JS • Ruby • PHP
  34. @syrusakbary Graphene.tools GraphQL-Quiver.com Interested?

  35. –Kenneth Reitz (creator of requests package in Python)
 @kennethreitz “PS.

    your API is a user interface”
  36. @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
  37. @syrusakbary Graphene.tools Questions? http://graphene.tools