{"id":120314,"date":"2026-07-03T10:50:46","date_gmt":"2026-07-03T05:20:46","guid":{"rendered":"https:\/\/www.guvi.in\/blog\/?p=120314"},"modified":"2026-07-03T10:50:48","modified_gmt":"2026-07-03T05:20:48","slug":"graphql-with-strawberry-tutorial","status":"publish","type":"post","link":"https:\/\/www.guvi.in\/blog\/graphql-with-strawberry-tutorial\/","title":{"rendered":"GraphQL with Strawberry Tutorial: Build Your First Python API"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>TL;DR Summary<\/strong><\/h2>\n\n\n\n<ul>\n<li>GraphQL with Strawberry is a Python library that lets you build GraphQL APIs using simple type hints<\/li>\n\n\n\n<li>You define your schema with Python classes \u2014 no separate schema files needed<\/li>\n\n\n\n<li>Supports queries, mutations, and subscriptions out of the box<\/li>\n\n\n\n<li>Works great with FastAPI and Django for production apps<\/li>\n\n\n\n<li>Beginners can get a working GraphQL API running in under 30 minutes<\/li>\n<\/ul>\n\n\n\n<p>Strawberry is a Python library for building GraphQL APIs using type annotations. You define your data types as Python dataclasses, decorate them with @strawberry.type, and Strawberry auto-generates a fully functional GraphQL schema.&nbsp;<\/p>\n\n\n\n<p>It works with FastAPI and Django, and lets beginners build type-safe APIs without writing raw SDL (Schema Definition Language).<\/p>\n\n\n\n<p>This tutorial walks you through everything from scratch \u2014 setting up your environment, writing your first schema, running queries, and handling mutations. By the end, you will have a working GraphQL API you can actually build on.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What Is GraphQL with Strawberry?<\/strong><\/h2>\n\n\n\n<p><a href=\"https:\/\/www.guvi.in\/blog\/what-is-graphql\/\" target=\"_blank\" rel=\"noreferrer noopener\">GraphQL<\/a> is a query language for APIs. Instead of hitting multiple REST endpoints, your client sends one request and specifies exactly which fields it needs. The server returns only that data \u2014 nothing more, nothing less.<\/p>\n\n\n\n<p><a href=\"https:\/\/strawberry.rocks\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\"><strong>Strawberry<\/strong><\/a> is a <a href=\"https:\/\/www.guvi.in\/blog\/what-is-a-python-library\/\" target=\"_blank\" rel=\"noreferrer noopener\">Python library<\/a> that brings GraphQL to Python in the most Pythonic way possible. It uses Python&#8217;s type hints and dataclass-style syntax, so if you have written modern Python, you will feel right at home.<\/p>\n\n\n\n<p>\ud83d\udcca <strong>Data Point:<\/strong> According to the 2025 Stack Overflow Developer Survey, GraphQL adoption has grown 38% year-over-year among backend developers, with Python being the third most common language used to build GraphQL APIs.<\/p>\n\n\n\n<p>Here is what makes Strawberry stand out from other Python GraphQL libraries like Graphene:<\/p>\n\n\n\n<ul>\n<li>Uses native Python type hints (no separate type definitions)<\/li>\n\n\n\n<li>Full async support out of the box<\/li>\n\n\n\n<li>Works natively with FastAPI, Django, and Flask<\/li>\n\n\n\n<li>Better IDE support and autocompletion<\/li>\n\n\n\n<li>Actively maintained with a growing community<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Setting Up Your Environment<\/strong><\/h2>\n\n\n\n<p>Let us get your machine ready. You will need Python 3.10 or higher.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1: Create a virtual environment<\/strong><\/h3>\n\n\n\n<p><code>python -m venv venv<\/code><\/p>\n\n\n\n<p><code>source venv\/bin\/activate&nbsp; # On Windows: venv\\Scripts\\activate<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 2: Install Strawberry with FastAPI support<\/strong><\/h3>\n\n\n\n<p><code>pip install \"strawberry-graphql[fastapi]\" uvicorn<\/code><\/p>\n\n\n\n<p>That is it. You are ready to write your first schema.<\/p>\n\n\n\n<p>\ud83d\udca1 <strong>Pro Tip:<\/strong> If you are using Django, install strawberry-graphql[django] instead. Strawberry has first-class support for both frameworks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How Does Strawberry Work?<\/strong><\/h2>\n\n\n\n<p>Strawberry turns your Python classes into a GraphQL schema automatically. You decorate your types with @strawberry.type and your resolver functions with @strawberry.field. Strawberry handles the rest \u2014 type mapping, schema generation, and introspection.<\/p>\n\n\n\n<p>Think of it this way: in REST, you define routes. In Strawberry GraphQL, you define types and queries \u2014 and the framework figures out how to expose them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Building Your First GraphQL Schema<\/strong><\/h2>\n\n\n\n<p>Let us build a simple book API. It will return a list of books and let you fetch a single book by ID.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1: Create main.py and define your types<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/python\n\nimport strawberry\n\nfrom typing import List, Optional\n\n@strawberry.type\n\nclass Book:\n\n&nbsp;&nbsp;&nbsp;&nbsp;id: int\n\n&nbsp;&nbsp;&nbsp;&nbsp;title: str\n\n&nbsp;&nbsp;&nbsp;&nbsp;author: str\n\n&nbsp;&nbsp;&nbsp;&nbsp;year: int\n\nThat single class<\/code><\/pre>\n\n\n\n<p> is now a valid GraphQL type. Strawberry reads your type hints and maps them to GraphQL scalar types automatically \u2014 int becomes Int, str becomes String, and so on.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 2: Add some mock data<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/python\n\nbooks_db = &#91;\n\n&nbsp;&nbsp;&nbsp;&nbsp;Book(id=1, title=\"Clean Code\", author=\"Robert C. Martin\", year=2008),\n\n&nbsp;&nbsp;&nbsp;&nbsp;Book(id=2, title=\"The Pragmatic Programmer\", author=\"David Thomas\", year=1999),\n\n&nbsp;&nbsp;&nbsp;&nbsp;Book(id=3, title=\"Fluent Python\", author=\"Luciano Ramalho\", year=2022),\n\n]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 3: Define your Query type<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/python\n\n@strawberry.type\n\nclass Query:\n\n&nbsp;&nbsp;&nbsp;&nbsp;@strawberry.field\n\n&nbsp;&nbsp;&nbsp;&nbsp;def books(self) -&gt; List&#91;Book]:\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return books_db\n\n&nbsp;&nbsp;&nbsp;&nbsp;@strawberry.field\n\n&nbsp;&nbsp;&nbsp;&nbsp;def book(self, id: int) -&gt; Optional&#91;Book]:\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return next((b for b in books_db if b.id == id), None)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 4: Create the schema and wire it to FastAPI<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/python\n\nimport strawberry\n\nfrom fastapi import FastAPI\n\nfrom strawberry.fastapi import GraphQLRouter\n\nschema = strawberry.Schema(query=Query)\n\ngraphql_app = GraphQLRouter(schema)\n\napp = FastAPI()\n\napp.include_router(graphql_app, prefix=\"\/graphql\")<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 5: Run the server<\/strong><\/h3>\n\n\n\n<p><code>uvicorn main:app --reload<\/code><\/p>\n\n\n\n<p>Open your browser at http:\/\/localhost:8000\/graphql and you will see Strawberry&#8217;s built-in GraphiQL playground \u2014 an interactive editor where you can run queries immediately.<\/p>\n\n\n\n<p>\u2705 <strong>Best Practice:<\/strong> Always run with &#8211;reload during development. It watches for file changes and restarts the server automatically \u2014 saves you from restarting manually every 5 minutes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Running Your First Query<\/strong><\/h2>\n\n\n\n<p>In the GraphiQL playground, paste this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/graphql\n\nquery {\n\n&nbsp;&nbsp;books {\n\n&nbsp;&nbsp;&nbsp;&nbsp;id\n\n&nbsp;&nbsp;&nbsp;&nbsp;title\n\n&nbsp;&nbsp;&nbsp;&nbsp;author\n\n&nbsp;&nbsp;}\n\n}<\/code><\/pre>\n\n\n\n<p>You will get back exactly those three fields for each book \u2014 not the year, because you did not ask for it. That is GraphQL&#8217;s core value: you control the shape of the response.<\/p>\n\n\n\n<p>To fetch a single book:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/graphql\n\nquery {\n\n&nbsp;&nbsp;book(id: 1) {\n\n&nbsp;&nbsp;&nbsp;&nbsp;title\n\n&nbsp;&nbsp;&nbsp;&nbsp;author\n\n&nbsp;&nbsp;&nbsp;&nbsp;year\n\n&nbsp;&nbsp;}\n\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Adding Mutations (Write Operations)<\/strong><\/h2>\n\n\n\n<p>Queries handle reads. Mutations handle writes \u2014 creating, updating, or deleting data.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/python\n\n@strawberry.type\n\nclass Mutation:\n\n&nbsp;&nbsp;&nbsp;&nbsp;@strawberry.mutation\n\n&nbsp;&nbsp;&nbsp;&nbsp;def add_book(self, title: str, author: str, year: int) -&gt; Book:\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_book = Book(\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id=len(books_db) + 1,\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;title=title,\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;author=author,\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;year=year\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;books_db.append(new_book)\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new_book<\/code><\/pre>\n\n\n\n<p>Now update your schema to include the mutation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/python\n\nschema = strawberry.Schema(query=Query, mutation=Mutation)\n\nRun this mutation in the playground:\n\ngraphql\n\nmutation {\n\n&nbsp;&nbsp;addBook(title: \"Python Tricks\", author: \"Dan Bader\", year: 2017) {\n\n&nbsp;&nbsp;&nbsp;&nbsp;id\n\n&nbsp;&nbsp;&nbsp;&nbsp;title\n\n&nbsp;&nbsp;}\n\n}<\/code><\/pre>\n\n\n\n<p>You will get back the newly created book with its ID. Clean, predictable, and easy to extend.<\/p>\n\n\n\n<p>\u26a0\ufe0f <strong>Warning:<\/strong> This tutorial uses an in-memory list for simplicity. In a real app, connect your mutations to a database using SQLAlchemy or Tortoise ORM. Never use mutable global state in production.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What to Do Next<\/strong><\/h2>\n\n\n\n<p>Now that you have a working GraphQL API, here is how to level it up:<\/p>\n\n\n\n<ol>\n<li><strong>Connect a real database<\/strong> \u2014 Use SQLAlchemy with async support for production-grade data access<\/li>\n\n\n\n<li><strong>Add authentication<\/strong> \u2014 Strawberry supports context injection, which makes JWT auth straightforward<\/li>\n\n\n\n<li><strong>Add subscriptions<\/strong> \u2014 Real-time updates with WebSockets, using @strawberry.subscription<\/li>\n\n\n\n<li><strong>Deploy to the cloud<\/strong> \u2014 Your FastAPI + Strawberry app works on Railway, Render, or AWS Lambda<\/li>\n<\/ol>\n\n\n\n<p>If you want a structured, mentor-supported path and learn all these new tools, then HCL GUVI\u2019s IIT-M Pravartak Certified <a href=\"https:\/\/www.guvi.in\/zen-class\/full-stack-development-course\/?utm_source=blog&amp;utm_medium=hyperlink+&amp;utm_campaign=graphql-with-strawberry\" target=\"_blank\" rel=\"noreferrer noopener\">Full Stack Developer Course<\/a> with AI Integration covers the entire journey, from HTML to deployment, with real projects, live sessions, and placement support. Over 10,000 students have used it to break into product-based companies.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Key Takeaways<\/strong><\/h2>\n\n\n\n<ul>\n<li>Strawberry makes GraphQL feel native to Python \u2014 no context switching<\/li>\n\n\n\n<li>Your schema lives entirely in Python \u2014 no SDL files to maintain separately<\/li>\n\n\n\n<li>Queries handle reads; mutations handle writes \u2014 the same pattern scales to large APIs<\/li>\n\n\n\n<li>The built-in GraphiQL playground is great for testing during development<\/li>\n\n\n\n<li>Strawberry integrates cleanly with FastAPI, making it easy to add to existing projects<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>FAQs<\/strong><\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1782994450377\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>What is GraphQL with Strawberry used for?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Strawberry is used to build GraphQL APIs in Python. It lets you define your schema using Python type hints and dataclasses, then exposes it as a fully functional GraphQL endpoint. It is popular for building flexible, efficient APIs where clients need to control what data they receive.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1782994464933\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>Do I need to know GraphQL before learning Strawberry?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Basic GraphQL concepts help, but you do not need deep expertise. If you understand what queries and mutations are, you can follow along with Strawberry from day one. The library&#8217;s Python-first approach makes it especially friendly for developers coming from a REST background.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1782994469287\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>Is Strawberry better than Graphene for Python?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>For most new projects in 2026, yes. Strawberry has better async support, native type hint integration, and cleaner FastAPI compatibility. Graphene has more legacy tutorials, but Strawberry&#8217;s developer experience and active maintenance make it the stronger choice going forward.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1782994475116\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>Can Strawberry GraphQL work with Django?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Yes, Strawberry has official Django support. Install strawberry-graphql[django], add it to your INSTALLED_APPS, and define a URL route pointing to Strawberry&#8217;s GraphQLView. It integrates with Django&#8217;s ORM and auth system without much extra setup.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1782994483559\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>How do I handle errors in Strawberry GraphQL?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Strawberry lets you raise Python exceptions inside resolvers and maps them to GraphQL errors automatically. For custom error handling, you can use strawberry.extensions or return a Union type that includes both success and error states \u2014 a pattern called the &#8220;result type&#8221; pattern.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1782994489355\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>Is Strawberry GraphQL production-ready?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Yes. Strawberry is used in production by multiple companies and has stable releases with semantic versioning. It supports async resolvers, dataloaders for batching database calls, custom directives, and extensions \u2014 everything you need for a serious API.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1782994495001\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>What Python version do I need for Strawberry?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Strawberry requires Python 3.8 or higher, but Python 3.10+ is recommended for the cleanest type hint syntax, especially when using X | Y union syntax instead of Optional[X].<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>TL;DR Summary Strawberry is a Python library for building GraphQL APIs using type annotations. You define your data types as Python dataclasses, decorate them with @strawberry.type, and Strawberry auto-generates a fully functional GraphQL schema.&nbsp; It works with FastAPI and Django, and lets beginners build type-safe APIs without writing raw SDL (Schema Definition Language). This tutorial [&hellip;]<\/p>\n","protected":false},"author":22,"featured_media":120462,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[429,294],"tags":[],"views":"34","authorinfo":{"name":"Lukesh S","url":"https:\/\/www.guvi.in\/blog\/author\/lukesh\/"},"thumbnailURL":"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/07\/GraphQL-with-Strawberry-300x116.webp","_links":{"self":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/120314"}],"collection":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/comments?post=120314"}],"version-history":[{"count":4,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/120314\/revisions"}],"predecessor-version":[{"id":120465,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/120314\/revisions\/120465"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/media\/120462"}],"wp:attachment":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/media?parent=120314"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/categories?post=120314"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/tags?post=120314"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}