Strawberry GraphQL

@strawberry-graphql

2023 Recap + What's next

strawberry-graphql

Hey folks! It's been a long time since we shared an update, but I’m going to write more posts on our progress and focus ahead - it’s a goal of mine for 2024 😊

Since our last update, a lot has happened... we have about 15 pages of releases on GitHub! I'll share some of the highlights later in this post, but first some updates on the future 👀

I’m excited to share some really cool news: We have a new core dev, Erik! Erik was (and still is) contributing to and maintaining Graphene (and Graphene SQLAlchemy) and he recently contributed support for FieldExtensions, helped me a lot with other features and started prototyping a partial rewrite in Rust of parts of our core.

I started Strawberry more than 5 years ago, and I've seen it grow a lot since. It’s also given me some amazing opportunities; getting accepted to the first GitHub accelerator program, new jobs and making new friends.

But during the last year or so I haven't managed to spend enough time on it… That will change this year. I’m eager to work more on Strawberry and simultaneously find ways to make it sustainable for me and the other Strawberry developers working on it.

On that note, if you work for a company using Strawberry: Consider sponsoring us, or putting me in touch with the people that could make a decision to sponsor us. We have plans to offer more benefits for sponsors, so we're interested in ideas from you (some ideas we had so far: organizing workshops, providing a few hours of support, private discord channel for support), but we are open to more things for sure 😊

On that note, we used to use mailchimp for this newsletter but we have moved it to Polar.sh. Polar is a new developer platform focused on empowering open source developers with better funding tools & community features that their users can benefit from. I think Birk and team are doing a lot of great work, and hopefully that work will help us get more subscribers and paid subscriptions for additional benefits to drive more funding behind Strawberry.

I’m excited about the future and investing more time in Strawberry personally. Combined with growing our community and offer exciting - additional - subscription benefits that can attract more funding & commercial support I believe we can make Strawberry the best GraphQL library out there (and not just for Python 😉)

Now, let’s dive into the things I’d love to ship this year:

New CLI

I have been wanting a cool CLI for Strawberry for a long time. We do offer a few commands, but I think they are hard to find and not that user friendly. I haven't started any work on this, but I'm sure it will happen at some point. We'll definitely also have new useful features like strawberry init which will start a new project using Strawberry (and the framework of your choice).

First class Pydantic support

This is the most requested feature by far, and we have an initial PR. I think the most difficult part is to find all the edge cases and possible things one can do using Pydantic+Strawberry, but I really think it is a valuable thing to have (especially for input types), so we’ll try to prioritize this! We also have an issue you can vote or fund here: https://github.com/strawberry-graphql/strawberry/issues/2181

New site

We are launching a new website very soon. It has a nicer home page, but also a much better documentation layout and typography. I always disliked the typography of our previous site, plus the dark mode is actually nice! If we haven’t launched this already you can check a preview here: https://beta.strawberry.rocks/ 👀

Rust + Performance

Erik has been working on replacing parts of Strawberry with Rust to improve performance. I think this will be one of the goals for this year, to make Strawberry as fast as possible. We are a bit restricted by GraphQL-core, but maybe we can contribute to it to make it faster, or we could make our own GraphQL executor 👀

More content

As I mentioned it's been ages since the last newsletter, I think that's not great for us, and for you too, we really need to keep you updated on our development and also give you more opportunities to interact with us. But I promise we won't send too many updates 😉

V1

We’ve had an issue open for v1 for a very long time, I know this is important for a few people so we’ll also try to prioritize getting v1.0 out for this year. I don’t personally think it’s a lot of work, but we need time to plan and make sure everything is well thought out.

Ok, with that done, let's do a recap, I've tried to mention the most interesting releases, but since that’s a personal preference, I'm sure I missed a few, I hope that’s ok! 😊

2023 - A recap

Better extensions authoring

https://github.com/strawberry-graphql/strawberry/pull/2428

Extensions hooks are now based on generators, which makes the code of the extensions much nicer 😊

This is how a hook looked previously:

def on_executing_start(self):  # Called before the execution start
    ...

def on_executing_end(self):  # Called after the execution ends
    ...

And this is how it looks now, much better, right? 😊

def on_execute(self):
    #  This part is called before the execution start
    yield
    #  This part is called after the execution ends

This was contributed by Nir: https://github.com/nrbnlulu

Field extensions

https://github.com/strawberry-graphql/strawberry/pull/2567

We now have support for field extensions, which allow you to customize pretty much everything on a field (type, name, arguments, resolver, etc).

This is a great feature that makes Strawberry much more extensible and reduces the amount of code that we need to maintain.

In fact we migrated our permission system to use field extensions and we implemented support for Relay pagination using field extensions as well.

This was contributed by Erik

HTTP integrations

Another big task was refactoring our HTTP integration, we support quite a few frameworks and the code was getting hard to maintain, as each integration was duplicating all the logic to deal with the GraphQL request. So we made a big refactor to improve this situation.

https://github.com/strawberry-graphql/strawberry/pull/2775

Now we have two base classes (one for sync and one for async) that are reused by the HTTP integrations. This made easier to add support for Litestar and Quart, but also for adding new features (like multipart subscriptions, which I’ll talk about in a new post, hopefully soon).

New extensions

We also have new extensions for improved security and for instrumenting:

We also improved existing extensions: https://github.com/strawberry-graphql/strawberry/pull/2505

Better codegen

Matt made a lot of improvements to Strawberry codegen to mainly resolve various issues and enhance its functionality. Fixes include proper location detection for types, correct emission of __typename field, enhanced handling of fragments, directory existence checks, optimized field detection, allowance of object arguments utilization, correction of type generation, improved type hints, better handling of default values, and capability to process multiple query files. A lot of stuff! Thanks Matt!

Schema codegen

We also released a codegen for converting your GraphQL schema (in SDL format) to Python code, this is pretty useful if you or your team likes using SDL for writing the specification, but still want to use a code first approach for the implementation.

https://github.com/strawberry-graphql/strawberry/pull/3096

Pydantic 2.0

Our experimental Pydantic integration now supports Pydantic 2 https://github.com/strawberry-graphql/strawberry/pull/2972 and thanks to https://github.com/tjeerddie for fixing various bugs that popped out after releasing the initial support 😊

Relay pagination

Thiago added support for the Relay spec: https://github.com/strawberry-graphql/strawberry/pull/2511, this makes it easier to implement relay pagination in your apps (we also use this in Strawberry Django and Strawberry SQLAlchemy)

Better internals

I’ve mentioned V1.0 above, one of things I want to make sure we get right (or at least, consistent) for V1.0 is how we store reference to the Strawberry types. We used to use _type_definition and we recently migrated that __strawberry_definition__ which is much more explicit now. Thanks Nir for the PR!

https://github.com/strawberry-graphql/strawberry/pull/2836

Better UX when upgrading

On a similar note, we also want to make the experience of upgrading Strawberry as seamless as possible. That’s why we released an upgrade command. The idea is that we’ll have codemods for deprecation and breaking changes, when possible.

https://github.com/strawberry-graphql/strawberry/pull/2886

Pythonic unions

Now you can use Annotated[Some | UnionType, strawberry.union("UnionName")] to define unions in a way that’s understood by all type checkers. We want to be fully compatible with Mypy and Pyright, so we’ll, over time, deprecate type creation functions that can’t be typed correctly (strawberry.scalar is another example).

strawberry.Parent

If you’ve used Strawberry for a while you know it is a bit confusing to use self/root, we hopefully made that better by creating a new type called strawberry.Parent, which refers to the parent of the current field (basically what self and root were used for previously). But now you can name the parent type anything you want, as long as you use strawberry.Parent. Thanks Matt for this improvement!

https://github.com/strawberry-graphql/strawberry/pull/3017

Support for 3.12

We added support for the new generic syntax in Python 3.12, which is much nicer to use!

https://github.com/strawberry-graphql/strawberry/pull/2993

More GraphQL IDEs

We also added support for Apollo Explorer, Pathfinder alongside the original GraphiQL IDE, now you can easily toggle between the 3 and use the one you like the most!

https://github.com/strawberry-graphql/strawberry/pull/3209

Better permissions

As I mentioned above Erik made a lot of improvements to our extensions and rewrote the permission system to use that. Now you can you have silent errors (for example you can just return None or an empty list without raising an error), you can customize the errors (for example to add an error code to the GraphQL error object) and you can also add schema directives to fields that have permission classes (which would show up in the exported schema). So cool!

https://github.com/strawberry-graphql/strawberry/pull/2570

Strawberry Django

Here's some updates on Strawberry Django:

What has happened

A lot has been going on in the Strawberry Django integration side.

On July 2023, the popular strawberry-django-plus library has been merged into the official integration repository, adding the following functionalities to it:

  1. Query optimizer: Probably the most popular feature of the library, which leverages introspection of queries and the ORM itself to automatically optimize QuerySets by calling .select_related(...)/.prefetch_related(...)/.only(...) for the selected fields.
  2. Permissioned resolvers: A set of field extensions that allows fields to dictate its permissioning using the django permissioning system.
  3. Relay support: While the original relay implementation has been adapted and contributed back to Strawberry itself, Strawberry Django will adapt your code using it to make sure your models are queried in the best way possible, without you having to write a lot of boilerplate code for every connection.
  4. Django debug toolbar support: A custom implementation of this popular library, allowing it to display request statistics inside the GraphQL Playground, that works with both WSGI (sync) and ASGI (async).
  5. Improved CUD mutations: Mutations have been improved, specially CUD ones. It is now possible to create/update nested objects, uploads are now supported, together with a lot of minor improvements and adjustments.

Since then, the community has been very active, contributing a lot of new features, improvements and documentation. Big shout out all contributors ♥️.

Here are the highlights of some new features:

  1. PR #299: New export_schema django command
  2. PR #293: Add new keywords "fields" and "exclude" to type decorator for auto-population of Django model fields
  3. PR #313: Support for AND, OR and NOT for filters
  4. PR #363: Support for inList for enums
  5. PR #377: Allow to define .annotate(...) hints for the optimizer
  6. PR #348: Optional custom key_attr to that can be used instead of id (pk) in to access model in Django CUD mutations
  7. PR #393: Compatibility ASGI/websockets get_request, login and logout

Djangocon talk

Thiago Bellini, the maintainer of the Strawberry Django integration, gave a talk about Building high-performance, type-safe GraphQL APIs with Strawberry and Django at Djangocon US 2023.

The talk was recorded and is now available on youtube at: https://www.youtube.com/watch?v=TP8MC2W3eIw

What's coming next

  • Optimization support for nested connections and lists: This has been one of the most requested features for a while and we plan to tackle this in the first quarter of 2024.
  • Ordering overhaul: The current ordering implementation is too simple. It works, but doesn't allow for more advanced usage, like our filtering does. We are still discussing if we can improve the current implementation, or if we implement a new one from scratch and deprecate the old one.
  • Docs need some love: Our current docs are not in the best shape! They lack examples for a lot of features that people will only know about if they read the source code. Some examples are also outdated and probably need to be rewritten. Lets give the docs some love this year! ♥️

If you read all of this, thank you! It means a lot, I know it was a big wall of text, but I promise we'll make more shorter updates in future :D

Thanks and see you soon!

Patrick