# Prisma Website - Full Content ## Web Pages & Blog Posts ## [Page not found | Prisma](/404) **Meta Description:** Prisma is the easiest way to access a database from a Next.js application in Node.js & TypeScript. **Content:** ## [404] ## 404 - Page not found We could not find the page you were looking for. Head back to our homepage or check out our documentation. We could not find the page you were looking for. Head back to our homepage or check out our documentation. --- ## [Error | Prisma](/500) **Meta Description:** Prisma is the easiest way to access a database from a Next.js application in Node.js & TypeScript. **Content:** ## Whoops! Something went wrong and we couldn’t find that page. Try heading to the homepage or reach out to us if you need help. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. --- ## [About | Prisma](/about) **Meta Description:** At Prisma, our mission is to provide the best experience for teams to work and interact with databases. Learn more about Prisma. **Content:** ## We simplify building with data Our mission is to unlock productivity for developers by bringing delightful ways to build with data. Data DX is at the core of all our products. ## Built on open source Prisma evolved from an open-source project to the most downloaded ORM in the Node.js ecosystem, powered by our commitment to improving DX and a strong community. ## Throughout the development lifecycle We equip developers with the right tools at every stage, whether they are building, fortifying, or growing their applications. ## Focused on Data DX Applying Data DX principles to all our products, we create simple solutions for complex problems, making building with data more accessible, regardless of team size. ## Our Investors CEO at Vercel Founder of Heroku Creator of GraphQL CEO at Kong Angel Investor AngelList Europe AngelList Europe CEO at Algolia GP at Mango Capital CEO Cockroach Labs Founder, GitHub CEO Planetscale Investor Co-founder Netlify VP, Product Marketing Temporal ## What we care about ## Open Source To support the OSS community and help fund the ecosystem around Prisma, we started our Free and Open Source Software (FOSS) Fund in April 2022. Each month Prisma donates a one-off amount of $500 to a selected open-source project. ## Climate change Prisma is committed to supporting initiatives that raise awareness about and combat the effects of climate change. We will all be affected by this, and we owe it to the places, people, and wildlife of this planet to make substantial changes and reduce our impact on the climate. ## Join the team We’re always excited to talk to more people who share our vision to empower developers to build data-driven applications. --- ## [Prisma Accelerate | Make your database queries faster](/accelerate) **Meta Description:** Accelerate is a managed connection pooler with global caching that helps you speed up your queries with just a few lines of code. **Content:** ## Make your database global Accelerate is a fully managed global connection pool and caching layer for your existing database, enabling query-level cache policies and flexible invalidation options directly from the Prisma ORM. ## Speed up database writes with connection pools in 15+ regions Enable highly scaleable and reliable serverless and edge workloads on managed infrastructure with full tenant isolation. Bring the connection pooler close to your database to decrease latencies. ## Supercharge database reads with caching in 300+ global locations Easily add query caching to your application in just a few lines of code, with no infrastructure to manage. Choose the right cache strategy for each of your queries, tailored exactly to your app. Accelerate scales up and down seamlessly and automatically, based on your app’s traffic. Built to handle any load you can throw at it. Decrease latencies by bringing the cached result closer to the user without changing anything in your database infrastructure. Get more out of the database you already have. Cut down on reads and compute by caching queries, optimizing resource usage and cost. ## Database access via Accelerate ~5ms response time ## Live Activity Track real-time global traffic as developers build and scale with our commercial products. ## Faster development, easy integration & setup Focus on the core competencies of your team. We'll take care of building and managing infrastructure components, and ensuring full tenant isolation for you. ## Great Prisma DX Caching that feels like part of your ORM and existing workflow, with type-safety and autocomplete. ## Prisma CLI Easily configure Accelerate without leaving your terminal and automate its configuration in your CI environments. ## Bring your own database Works with the database you already have, whether it's publicly accessible, or via an IP allowlist. If you switch down the line, it’s as easy as updating your connection string. ## A unified space for team collaboration on projects The Platform Console allows you to configure features, collaborate on projects, manage membership and billing directly within each workspace. ## Works the way you do Reflect the way you and your team develop projects with workspaces, projects and environments. ## Explore your usage Monitor queries served and cache utilization through the insights dashboard. Compare latency of cached and non-cached queries to understand the impact on application and database performance. ## How you can use Accelerate ## Content-first applications Accelerate is perfect for blogs or applications with high demand. ## Pricing that scales with you Prisma Accelerate is priced based on usage. Choose the right plan for your workspace based on your project requirements. ## Make your database queries faster Simply enable Accelerate on a new or existing project, add it to your app, and start using in your database queries. --- ## [Apollo & Prisma & Database | Next-Generation ORM for SQL Databases](/apollo) **Meta Description:** Prisma is a next-generation ORM. It's the easiest way to build a GraphQL API with Apollo Server and MySQL, PostgreSQL & SQL Server databases. **Content:** ## Easy, type-safe database access with Prisma & Apollo Query data from MySQL, PostgreSQL & SQL Server databases in GraphQL with Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and Apollo fit together Apollo provides a great ecosystem for building applications with GraphQL. When building GraphQL APIs with Apollo Server against a database, you need to send database queries inside your GraphQL resolvers – that's where Prisma comes in. Prisma is an ORM that is used inside the GraphQL resolvers of your Apollo Server to query your database. It works perfectly with all your favorite tools and libraries from the GraphQL ecosystem. Learn more about Prisma with GraphQL. ## Prisma Schema The Prisma schema uses Prisma's modeling language to define your database schema. It makes data modeling easy and intuitive, especially when it comes to modeling relations. You can also supercharge usage of Prisma ORM with our additional tools:• Prisma Accelerate is a global database cache and scalable connection pool that speeds up your database queries.• Prisma Pulse enables you to build reactive, real-time applications in a type-safe manner. Pulse is the perfect companion to implement GraphQL subscriptions or live queries. ## Prisma and Apollo use cases Prisma can be used in the GraphQL resolvers of your Apollo Server to implement GraphQL queries and mutations by reading and writing data in your database. It is compatible with Apollo's native SDL-first approach or a code-first approach as provided by libraries like Nexus or TypeGraphQL. ## Apollo Server — SDL-First When using Apollo's native SDL-first approach for constructing your GraphQL schema, you provide your GraphQL schema definition as a string and a resolver map that implement this definition. Inside your resolvers, you can use Prisma Client to read and write data in your database in order to resolve the incoming GraphQL queries and mutations. ## Apollo Server — SDL-First When using Apollo's native SDL-first approach for constructing your GraphQL schema, you provide your GraphQL schema definition as a string and a resolver map that implement this definition. Inside your resolvers, you can use Prisma Client to read and write data in your database in order to resolve the incoming GraphQL queries and mutations. "Prisma provides an excellent modeling language for defining your database, as well as a powerful ORM for working with SQL in JavaScript & TypeScript. It's the perfect match to Apollo Server and makes building GraphQL APIs with a database feel delightful." ## Why Prisma and Apollo? ## End-to-end type safety Get coherent typings for your application, from database to frontend, to boost productivity and avoid errors. ## Optimized database queries Prisma's built-in dataloader ensures optimized and performant database queries, even for N+1 queries. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Intuitive data modeling Prisma's modeling language is inspired by GraphQL SDL and lets you intuitively describe your database schema. ## Easy database migration Map your Prisma schema to the database so you don't need to write SQL to manage your database schema. ## Filters, pagination & ordering Prisma Client reduces boilerplates by providing convenient APIs for common database features. ## Featured Prisma & Apollo examples A comprehensive tutorial that explains how to build a GraphQL API with Apollo Server and Prisma and deploy it to DigitalOcean's App Platform. A ready-to-run example project with an SDL-first schema and a SQLite database A ready-to-run example project with Nexus (code-first) and a SQLite database ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Prisma Blog | Articles & Updates | Prisma, ORMs, Databases](/blog) **Meta Description:** Stay up to date with the latest from Prisma. Guides, announcements, and articles about Prisma, ORMs, databases, and the data access layer. **Content:** ## Prisma Blog Guides, announcements and articles about Prisma, databases and the data access layer. --- ## [Careers | Prisma](/careers) **Meta Description:** See open positions at Prisma. Join us to empower developers to build data-intensive applications. **Content:** ## Join Prisma Help us empower developers to build data-driven applications. ## Why Prisma? ## Solve challenging technical problems ## Flexible work environment ## Fully remote organization ## Working at Prisma ## Our values ## Benefits Stock options package with a maximum exercise period of 10 years after grant Generous recurring tech budget and subsidy for an ergonomic chair 24 vacation days per year in addition to sick leave and public holidays 20 weeks paid parental leave and 10 days paid time off per year in the event of the sickness of your child 4 mental health days per year 6-week paid sabbatical leave after three years Access to co-working spaces in your area Dedicated People and Operations team Two company offsites each year [US] 401K matching as well as medical, dental, and vision cover ## Open roles Filter by department --- ## [Prisma | Changelog](/changelog) **Meta Description:** All the latest Prisma product related updates, features, and improvements. **Content:** ## Changelog Here you’ll find all improvements and updates we’ve made to our products. ## 🤖 MCP Server for Prisma Postgres Prisma Postgres is the first serverless database without cold starts. Designed for optimal efficiency and high performance, it's the perfect database to be used alongside AI tools like Cursor, Windsurf, Lovable or co.dev. In the v6.6.0 ORM release, we added a command to start a Prisma MCP server that you can integrate in your AI development environment. Thanks to that MCP server, you can now: … and much more. To get started, add this snippet to the MCP configuration of your favorite AI tool and get started: Read more about the MCP server on our blog: Announcing Prisma's MCP Server: Vibe Code with Prisma Postgres ## 🚀 Prisma ORM 6.6.0 Prisma ORM v6.6.0 comes packed with amazing features: ## A modern and flexible prisma-client generator with ESM support (Early Access) In v6.6.0, we introduced a new prisma-client generator that's more flexible, comes with ESM support and removes any magic behaviours that may cause friction with the current prisma-client-js generator. Here are the main differences: Here's how you can use the new prisma-client generator in your Prisma schema: 📚 Learn more in the docs. ## Cloudflare D1 & Turso/LibSQL migrations (Early Access) Cloudflare D1 and Turso are popular database providers that are both based on SQLite. While you can query them using the respective driver adapter for D1 or Turso, previous versions of Prisma ORM weren't able to make schema changes against these databases. With the v6.6.0 release, we're sharing the first Early Access version of native D1 migration support for the following commands: 📚 Learn more in the docs: ## 😎 npx prisma init --prompt "An encyclopedia for cats" You can now pass a --prompt option to the prisma init command to have it scaffold a Prisma schema for you and deploy it to a fresh Prisma Postgres instance: For everyone, following social media trends, we also created an alias called --vibe for you 😉 ## 🧑‍🚀 More from the Prismasphere ## 🦀 Rust to TypeScript update Our ORM team is making progress on our transition from Rust to TypeScript. We've developed a migration plan and now have an initial prototype with benchmarks! This quarter we will be keeping our momentum by releasing support for different databases one by one. You can read up on that in our latest ORM Roadmap. ## 🔒 Prisma ORM 6.5.0 Prisma ORM 6.5.0 has been released with two big items! First, we no longer support the resetting of a database via the prisma migrate dev command. If a schema drift is detected, or if the migration is unable to be cleanly applied, we will print an error and suggest a workaround like the already existing prisma migrate reset command. Second, we’re expanding the responsibilities of the new prisma.config.ts file to include Studio! Now, you’ll be able to run Prisma Studio backed by modern Prisma ORM features like driver adapters. Check out our Prisma Config docs to learn more. ## ✍️ New content in the Prismasphere ## 🐘 Prisma Postgres®️ is GA! Prisma Postgres, our hosted PostgreSQL offering, is ready for production! We’re really excited to finally have a database offering, especially since Prisma Postgres comes standard with: For more info, be sure to check out our blog post on Prisma Postgres. If you’re feeling eager, you can get started with our new --db flag in prisma init We’re also ready to see Prisma Postgres everywhere. With our Instant Prisma Postgres initiative, Prisma Postgres will be available via LLMs so that you can get a database for your next project instantly. ## 🔧 Prisma ORM 6.4.0 Prisma ORM 6.4.0 has been released and has some great new features: ## new prisma.config.ts file With Prisma ORM 6.4.0, we’re introducing a new configuration file for Prisma ORM in Early Access. If you’d like to give it a try, just create a prisma.config.ts file like this one: To learn more, check out our documentation. ## 🎨 Improved Optimize Onboarding Prisma Optimize is our cloud-based tool for diagnosing slow queries or potential problems in your applications. We recently overhauled our onboarding so you can get from signup to optimizing, faster! ## ✍️ New content in the Prismasphere As always, we have a number of great articles shared by our team. Here are some highlights: GreatFrontEnd helps devs excel: GreatFrontEnd helps prospective front end developers ace interviews. Learn about their platform and how Prisma powers it! The Life of a Prisma Postgres Query: Prisma Postgres is slick, but there’s a lot of technology under the hood. Read on to learn how your queries traverse our infrastructure. Prisma Postgres in your favorite environment: Our goal is to make your development life easier. When it comes to Prisma Postgres, that means making sure it works with your development environment. Learn how we’re making sure that accessing Prisma Postgres is seamless in Netlify, IDX, Vercel, and beyond! Best Practices for Prisma ORM and Cursor: LLM-augmented IDEs are doing wonders for developer productivity. To get the most out of them with your Prisma ORM projects, check out this handy guide! ## 🎨 Prisma Studio We’ve released a new version of Prisma Studio! This version is packaged with Prisma ORM 6.3.0 and also marks the triumphant return of Prisma Studio in the Console. Be sure to check out our blog post for all the details, but here’s a shortlist: These changes are live for databases connected to the Prisma Data Platform and for projects using Prisma ORM 6.3.0. Just use npx prisma studio! ## 📊 Prisma ORM v6.3.0 released Alongside Prisma Studio updates, Prisma ORM 6.3.0 comes with some quality of life fixes that should make your experience even better. As always, check out the release notes for all the details. ## 🫣 Preview features no longer uncertain In our ORM Manifesto we noted that we had several Preview features that have gone stale with no updates in several years. We’re happy to report that our ORM team has gone through the existing features and their implementations and provided a plan on our GitHub on how they will be tackled! As a reminder, once a feature enters Preview, we plan to retire or promote that feature within the next three month period. ## ✍️ New content in the Prismasphere We’re busy writing to make sure that your Prisma experience is the best it can be. Here’s what we’ve been cooking up: And much more! Be sure to check out our X, BlueSky, and YouTube accounts for all the latest content. ## 🚀 Prisma ORM v6.2.0 released Prisma ORM 6.2.0 might be a minor release, but the changes in it are major. In this release we are moving the omit API (our most requested feature) to Generally Available. You can now use the omit API without a Preview feature flag! 6.2.0 also includes some other highly requested features: As always, check out the release notes for all the details. ## 🤖 Ask AI makes its way to the Console We’ve been using kapa.ai in our docs for a while now and have nothing but good things to say! So much so that the Ask AI functionality is now integrated in the Prisma Console. You can get answers tailored for you and the content you’re viewing 🤩 ## 🔍 New Optimize recommendations We’re continuing to improve Prisma Optimize with five new recommendations to help your database’s performance: ## 📈 Over 15B Accelerate queries and 10K Prisma Postgres Databases It seems like just yesterday that Prisma Accelerate hit a billion queries, but now we’re soaring past that. In addition to 15 billion Prisma Accelerate queries, we’re also happy to see our newest product, Prisma Postgres, hit ten thousand databases created. Thank you to everyone who has tried out Prisma Postgres during Early Access! ## ✍️ New content in the Prismasphere The weather might be cooling down this winter, but our team’s writing is heating up! Over the past three weeks we talked about: And much more! Be sure to check out our X, Bluesky, and YouTube accounts for all the latest content. ## 🤝 Share our posts near and far As you might have noticed on this exact page, we now have a new share feature! Across our blog and changelog we have an easy share button for X, Bluesky, LinkedIn, and beyond! ## 🚀 Prisma ORM v6.1.0 released We’re really excited about Prisma ORM 6.1.0 as our tracing Preview feature is now stable! There are a few changes needed if you are using the tracing feature, make sure you check out the release notes for all the details. ## 📜 Our Manifesto for Prisma ORM Another huge announcement for the ORM: we have published a Manifesto describing our view of the ORM and how we will tackle governance moving forward. You should read the whole document, but to spoil it a little bit: expect quarterly roadmaps, a leaner and meaner ORM, and an easier path for collaboration and contribution. ## 📊 Prisma Studio for Prisma Postgres Following up our announcement of Prisma Postgres and then moving Prisma Postgres to free for the Early Access period, we now have Prisma Studio available for Prisma Postgres! Prisma Studio, embedded directly in the Prisma Console, allows you to view and edit your data online. ## 🔍 New Optimize recommendations Prisma Optimize keeps getting better, with two new recommendations to help improve your database’s health: 💸 Improve efficiency by avoiding @db.Money ⏰ Avoid @db.timestamp(0) and @db.timestamptz(0) because of time rounding errors. ## 🌍 Where in the world are Prisma Accelerate users? We released a live activity view of Prisma Accelerate queries around the world! It’s awesome to see developers around the world using Prisma Accelerate to scale their projects. ## ✍️ New content in the Prismasphere The Prisma team has been hard at work writing as well as building. ## 🤝 Thanks As we wrap up this installment of the Changelog (and 2024!), the Prisma team wants to thank our community. In addition to the ORM Manifesto where we re-commit ourselves to the community, we also are celebrating 40,000 stars on our GitHub repo. We’ve come a long way, but this is only the beginning for Prisma and we couldn’t be happier having you along with us. ## 🚀 Prisma ORM v6 has arrived Prisma 6 is here, bringing improvements for future-proofing and enhanced performance. We've updated the minimum supported versions of TypeScript and Node.js and significantly improved full-text search capabilities by promoting the fullTextIndex and fullTextSearch features to General Availability. ## 💚 Prisma Postgres is free in early access Our new serverless PostgreSQL database, Prisma Postgres, remains free during its Early Access phase! Learn more about this on our blog. We're also gathering feedback on connecting to Prisma Postgres from your favorite database management tools, like TablePlus or PgAdmin. Let us know what you think here: pris.ly/i-want-tcp. If you've tried Prisma Postgres and have suggestions for improving it to better suit your use case, please provide your feedback here: pris.ly/ppg-feedback. ## 💬 We value your feedback! At Prisma, we're always striving to enhance your development experience. If you've recently worked with Prisma ORM or Prisma’s commercial offerings, we'd love to hear from you! Your insights are invaluable in shaping the future of our tools. 👉 Share your thoughts in this quick 2-minute survey. ## 🐘 Prisma Postgres® Our biggest news yet: Prisma now offers a managed PostgreSQL service! Entering Early Access, Prisma Postgres is a pay-as-you-go, serverless Postgres offering that offers competitive pricing and no cold starts! We’re confident that the technology powering Prisma Postgres is the path forward for database offerings. So much so that we’ve gone in depth on our blog on how we brought Prisma Postgres to life. ## 📈 Prisma ORM 5.22.0 We’re continuing to improve the Prisma ORM experience with Prisma ORM 5.22.0. In this release we focused on improving the tracing Preview feature and fix annoying bugs in metrics and connection pooling. More info available in our release notes! ## 👀 Prisma in the wild Every so often we get to work with others in making great examples that show off what is possible when you use Prisma. We’re super happy to show off a recent collaboration with trigger.dev that allows you to create a powerful, scalable, video processing pipeline. We also have heard from the community that when checking out our tools for the first time, it can be confusing on where to start. To help that, we’ve begun creating starter projects that show how to get started with a specific product. Today we’d like to highlight our Optimize starter project available via try-prisma! ## 🔍 More recommendations available in Prisma Optimize With this release, Prisma Optimize brings two new recommendations to help you enhance the performance of your database operations. Explore the new insights and take full advantage of our optimization engine to streamline your development experience. Resolve repeated queries with caching Prevent over-fetching with specific selects ## Compliance and certification information now found in Organization Settings Did you know that Prisma is GDPR, HIPAA, ISO 27001 and SOC-2 Type II compliant? It was a ton of work but we did it! And now, we’ve made it easier to stay on top of compliance and certification requirements. You can now view detailed compliance documentation, certifications, and audit logs directly in your Workspace Settings. This addition simplifies governance and helps you ensure that your organization meets the necessary standards for security and data protection. For further information into our certifications please refer to our Trust Center: https://trust.prisma.io/ ## 🎨 A fresh coat of paint on our blog, including search! Our blog just got a facelift! In addition to the brand new look and feel, we’ve introduced search to help you find posts faster. Whether you’re looking for product updates, tutorials, or community stories, our improved blog experience makes it easier than ever to stay informed. Check out the new landing page: https://www.prisma.io/blog ## Prisma ORM 5.21.0 Prisma ORM 5.21.0 brings some bug fixes and needed enhancements so that we can move our tracing Preview feature to GA. More info in our release notes! ## Hiring We're growing! If you’re passionate about developer tooling and want to contribute to the future of databases, we want to hear from you. Prisma is currently hiring across multiple teams, including engineering, developer advocacy, and product. Visit our careers page to learn more and see if there's a role that fits your skills. ## Prisma Optimize is now in GA! Prisma Optimize is now in GA, offering AI-powered tools to analyze and improve database query performance. It identifies problematic queries, provides actionable insights like reducing excessive rows or adding indexes, and allows you to track performance improvements in real-time. For more details, read the announcement blog post. ## 🚀 Announcing on-demand cache invalidation for Prisma Accelerate Now, you can cache query results longer and invalidate them when your data changes. This helps you keep your data fresh while maintaining peak performance. 🔖 Check out the blog 📄 Read the docs ## Increased query limits for Prisma Accelerate This highly requested feature allows you to configure query limits based on your pricing plan to handle longer database query durations or retrieve larger response sizes. 👉 Explore the details in our docs ## Introducing strictUndefinedChecks feature in Preview! With Prisma ORM 5.20.0, the Preview feature strictUndefinedChecks will disallow any value that is explicitly undefined and will be a runtime error. This change is direct feedback from this GitHub issue and follows our latest proposal on the same issue. If you want to read and learn more, take a look at our latest release notes! ## Build real-time workflows with Pulse & Inngest 🤝 We teamed up with Inngest to demonstrate how you can build powerful, extensible, real-time workflows using Prisma Pulse and Inngest together. Check it out ## Why choose Prisma for your data layer? Thousands of developers use Prisma for our popular TypeScript ORM, seamless connection pooling, advanced caching, real-time event streaming, and insightful query optimizations. 👉 Discover how our products work together to enable type safety, productivity, and flexibility in our blog post ## Meet TypedSQL: Bridging Type Safety with raw SQL in Prisma We're excited to introduce TypedSQL in Prisma ORM, a new feature that brings type safety to your raw SQL queries. With TypedSQL, you can write raw SQL in .sql files and enjoy the benefits of type-checking and auto-completion, all within your Prisma projects. Simply use the prisma generate --sql command to integrate these queries and execute them using the $queryRawTyped function. This update bridges the gap between the flexibility of raw SQL and the safety of Prisma, making your development process smoother and more reliable. To learn more and get started with TypedSQL, read our docs and check our latest blog post and video! ## Prisma Accelerate just got smarter: Discover Auto-Scaling We're excited to introduce auto-scaling for Prisma Accelerate, a feature designed to scale your applications seamlessly based on demand. With this new capability, Prisma Accelerate automatically adjusts resources to ensure optimal performance, whether you're dealing with a sudden traffic spike or steady growth. This means less manual intervention and more focus on building your application. We're committed to making your development experience as smooth as possible, and auto-scaling is a big step in that direction. Learn more about how connection pooling helps your applications and some best practices for setting the connection limit in our blog post. ## Boost security with Static IPs in Prisma Pulse Prisma Pulse now supports static IPs, enhancing security by allowing you to control access to your Prisma Data Platform with fixed IP addresses. This feature ensures that only trusted networks can interact with your data, providing an extra layer of protection for your applications. It's all about giving you more control and peace of mind when managing your data. Check our latest post and go to the platform console to get started. ## Easily set up Pulse with your Neon database Prisma Pulse is now a fully supported integration for Postgres databases on Neon. Get started today by reading our guide. ## Prisma ORM hit #1 on npm as the most downloaded Node.js ORM! Prisma ORM was released for production in 2021 and recently became the most downloaded database library on npm! We wouldn’t be here without your amazing support 💜 Check out our latest blog post where we reflect on our journey and share what's next for Prisma. ## Native support for UUIDv7 🎉 You can now use the latest version of UUIDs with Prisma ORM, providing even more flexibility and future-proofing for your applications. To support this, we’ve updated the uuid() function in Prisma Schema to accept an optional integer argument. Right now, the only valid values are 4 and 7, with 4 being the default. More details in our latest release notes. ## Pulse bug fixes 🛠 Resolved Pulse .stream() API Event Loss We’ve fixed an issue where the Pulse .stream() API would unexpectedly stop receiving events, requiring a manual disconnect and reconnect. This was due to a race condition in the Pulse backend, which has now been identified and corrected. Your event streams should now be more reliable and uninterrupted. 🚀 Enhanced Error Feedback during Pulse Setup We’ve improved the error messages you receive during the Pulse setup. Previously, users with certain unsupported database configurations encountered generic error messages. Now, Pulse provides clearer, more instructional feedback to help you resolve these issues more efficiently. ## New Accelerate examples projects 🔍 Dive into our latest example apps with Nuxt.js, SolidStart, and SvelteKit and learn how to implement Prisma Accelerate and apply effective cache strategies to speed up data retrieval. Check out the code example for your preferred framework ## ORM benchmarks Performance is an important topic for us at Prisma! 📊 That’s why we created open-source benchmarks that compare Prisma ORM, Drizzle ORM, and TypeORM using PostgreSQL databases hosted on AWS RDS, Supabase, and Neon. Read more about our methodology, see a summary of the results, and learn how to ensure your Prisma ORM queries are at optimal speed. ## AWS Marketplace listing Prisma Accelerate and Prisma Pulse are now available on the AWS Marketplace! Simplify your infrastructure management with seamless integration and unified billing. Discover how to get started with Prisma on AWS today in our blog post. ## Share your feedback about Prisma ORM We want to know how you like working with Prisma ORM in your projects! Please take our 2min survey and let us know what you like or where we can improve 🙏 ## QueryRaw performance improvements We’ve changed the response format of queryRaw to decrease its average size, which reduces serialization CPU overhead. Here’s a peek at the results measuring before and after the improvements. When querying large data sets, we expect you to see improved memory usage and up to 2x performance improvements, as you can clearly see in the graphs. We are very excited to introduce these improvements in our latest 5.17.0 release! ## VSCode extension improvements In 5.17, we introduced some quality of life improvements for our VS Code extension, which makes interacting with it so much better! Some of the additions were: Find out more in our latest release notes. ## Going beyond Prisma ORM Already building with Prisma ORM? Explore how Prisma Accelerate and Prisma Pulse help you develop faster, more scalable applications with real-time features your users are looking for in our new docs page: Going Beyond Prisma ORM. We take a look at common problems that arise as you're building applications, and how Accelerate and Pulse take your application to the next level after the Prisma ORM. ## Check how Solin uses Prisma Accelerate to serve 2.5M database queries per day Solin, a leading fitness marketplace for creators, has improved its platform by integrating Prisma Accelerate. This story highlights how Prisma Accelerate has contributed to Solin's success by enhancing performance and reliability with its scalable connection pool and global database cache. Check out our blog post and learn more about their architecture and the fantastic results they have obtained with Accelerate! ## Cloud connectivity report As we run on AWS & Cloudflare, we collect extensive latency data between them. We think you'll find this data as interesting as we do, so we’re excited to share our 1st annual Cloud Connectivity report! Read the report here and dive into all the nitty gritty about latency with us. ## Omit model fields globally In 5.13.0, we introduced Preview support for the omit option within the Prisma Client query options. Now, we’re more than happy to announce that we’re expanding the omitApi Preview feature to also include the ability to omit fields globally. Here's an example how you’re able to define fields to omit when instantiating Prisma Client either locally or globally: Read more in our latest blog post. ## Changes to prismaSchemaFolder preview feature To continue improving our multi-file schema support, we have a few breaking changes to the prismaSchemaFolder feature: When using relative paths in Prisma Schema files with the prismaSchemaFolder feature, a path is now relative to the file it is defined in rather than relative to the prisma/schema folder. We realized that during migration many people would have prisma/schema as well as prisma/schema.prisma. Our initial implementation looked for a .prisma file first and would ignore the schema folder if it exists. This is now an error. ## GitHub or Google... 🤔 With the new Google authentication option, the choice is yours when signing in on http://console.prisma.io. Stay tuned for more authentication options! ## Achievement Unlocked: Compliance for SOC2 Type II, HIPAA, GDPR, and ISO27001 Prisma has successfully implemented processes and controls required for SOC2 Type II, HIPAA, GDPR, and ISO 27001:2022 certifications. These accomplishments demonstrate our commitment to providing secure and reliable software solutions for developers working with databases. Read more in our blog post. ## 🚀 Introducing the Prisma Nuxt module Simplify setting up Prisma ORM in your Nuxt app and explore Prisma Studio in Nuxt Dev tools. Read more in our blog post. ## Prisma badges are now available Built something awesome with Prisma? 🌟 Show it off with these badges, perfect for your readme or website. Learn more about embedding the badges. ## Introducing Delivery Guarantees for Database Change Events Pulse makes it easy to build event-driven apps by letting you react to changes in your database. Thanks to its new event persistence feature, all database change events are now guaranteed to be delivered at least once and in the right order! Interested in learning more and trying Pulse for yourself? Dive into our blog post and get started! ## Organize your Prisma Schema into Multiple Files in v5.15 We are excited to introduce a new Preview feature in Prisma ORM: the ability to organize your Prisma Schema into multiple files. This highly requested feature is now available in our 5.15.0 release! Learn how it works in our latest blog post, and try it out yourself. Happy coding! ## Bringing Prisma ORM to React Native and Expo Have you considered building React Native apps using Prisma and Expo? Well, Prisma ORM now provides Early Access support for React Native and Expo, fulfilling a popular community request! Check out our blog post and public repo to get started! ## Prisma Insider Program We are happy to announce the launch of the Prisma Insider Program! Get early access to features, provide invaluable feedback, and play a key role in the development of Prisma’s commercial products. 👉 Check the details in our blog post. Follow this link to apply and tell us why you’d be a great fit for the Prisma Insider Program. ## Connection Pooling for High-Traffic Apps Connection pooling is crucial to ensure your data-driven app can handle massive loads without failure. Our blog post explores how connection pooling can save your e‑commerce platform during peak traffic, such as Black Friday. ## How Per-Query Caching Keeps your App Fast Find out how caching database queries can save you time and complexity and make your app run smoother and faster. 📚 Learn about the benefits of caching, when to use it, and how easy it is to set up with Prisma Accelerate in our blog post. ## New product announcement: Prisma Optimize 🔍 Ever wondered what SQL the Prisma ORM generates under the hood? Want to understand the performance of your app and deliver a better and faster experience for your users? With Prisma Optimize you can! 🎥 Watch our video walkthrough using dub.co as a case study. Read the announcement blog post for instructions on how to get started and optimize your own application. ## Introducing new Prisma client query: createManyAndReturn() In our 5.14.0 release, we made available a new, top-level Prisma Client query: createManyAndReturn(). It works similarly to createMany() but uses a RETURNING clause in the SQL query to retrieve the records that were just created. Here’s an example of creating multiple posts and then immediately returning those posts. Read more in our release notes ## MongoDB performance improvements Previously, Prisma ORM suffered from performance issues when using the in operator or when including related models in queries against a MongoDB database. With 5.14.0, Prisma ORM now rewrites queries to use a combination of $or and $eq operators, leading to dramatic performance increases for queries that include in operators or relation loading. See the closed public issues in our release notes. ## Prisma ORM Benchmark Curious to see how Prisma ORM performs with popular DB providers? We’ve worked with Vercel to add ORMs to their open-source database latency benchmarks. 🚀 Run the test and see for yourself! ## Documentation Updates Explore Pulse’s features and use cases in our updated documentation and follow our get-started guide to set up Pulse in minutes. In our Platform docs, we’ve refined the descriptions of Workspaces, Projects, and Environments and our billing information to make managing your projects and understanding your costs even easier. ## Introducing our Build, Fortify, Grow Framework Learn how Prisma products interoperate at each stage to enhance your data-driven application development process. 👉 Read up on the Prisma BFG framework ## Discord is where it’s at! 🤖 As of 1 May 2024, we've transitioned from our community Slack to our Discord server. Join us over there to showcase your projects, get community support, or simply meet & chat with your fellow devs. See you on Discord! ## Introducing Static IP Support in Prisma Accelerate Prisma Accelerate introduces Static IP support, enabling secure connections to your database with predictable IPs for controlled access and minimized exposure. This allows connections from Accelerate to databases requiring trusted IP access. Learn more in our blog post, and try it out. ## omit Fields From Prisma Client Queries (In Preview) We’re excited to announce Preview support for the omit option within the Prisma Client query options. The highly-requested omit feature now allows you to exclude fields that you don’t want to retrieve from the database on a per-query basis. Here is an example of using omit: Many users have requested a global implementation of omit. This request will be accommodated in the future. In the meantime, you can follow the issue here. Read more in our latest release notes ## Doc Updates The same docs that you know and love, but now built with Docusaurus! 🦖 👉 Enjoy an improved dark/light mode, search, layout, and Kapa AI experience. Visit our Docs or peek under the hood at https://github.com/prisma/docs ## Introducing Cloudflare D1 (Preview) Exciting news! 5.12.0 release brings Preview support for Cloudflare D1 with Prisma ORM 🥳 D1 is Cloudflare's native serverless database and was initially launched in 2022. It's based on SQLite and can be used when deploying applications with Cloudflare. Cloudflare has recently announced launching D1 in GA and we couldn't be happier to be adding support and working with them on this new milestone. Read more in our latest blog post. ## Implementing createMany() for SQLite Bringing support for createMany() in SQLite has been a long-awaited and highly requested feature ⭐ createMany() is a method on Prisma Client, released back in version 2.16.0, that lets you insert multiple records into your database at once. This can be really useful when seeding your database or inserting bulk data. Read more in our latest release notes. ## Platform Console Updates We have refined our subscription management for a better UX experience. Here are some cool new additions and improvements: • We've added support for more payment methods and you can now manage your Tax Ids • You can now see your invoice history and download past invoices. Try it out at console.prisma.io ## 📚 Documentation • Improved our getting started docs for Prisma Pulse and Railway • Improved our troubleshooting guide for Prisma Accelerate, so you can more easily resolve common issues you might run into. ## Stay in the Loop 🔍 • We’ll be at Epic Web Conference on April 11th, find us if you’re there! • Plus, you can now follow our updates on our brand new WhatsApp channel. Join and get the Changelog news delivered straight to you. ## Pulse in General Availability We're thrilled to announce that Pulse has reached General Availability! This marks a significant milestone in our journey to redefine how developers interact with database-event driven compute. Pulse is managed database-event infrastructure that simplifies database-event driven compute, making it easy to power real-time functionality, like chat, notifications, data broadcast, and more. Pricing? Start for free with our usage-based pricing, designed to scale flexibly with your project. 👉 Check out our announcement blog post and documentation to learn more and get started. ## Introducing Platform Environments Platform Environments is a new feature of the Prisma Data Platform that lets users create different setups within one project. This helps smoothen out the app development process, from testing to going live. Also, now you can access the Prisma Data Platform using the Prisma CLI, making it easier to manage your resources and workflow (currently in Early Access). 👉 Learn more in our blog post, and take it for a spin. ## Prisma ORM Edge Functions Support in Preview Prisma ORM now supports edge functions, allowing developers to access their databases using Prisma ORM from platforms such as Vercel Edge Functions, Vercel Edge Middleware, Cloudflare Workers, and Cloudflare Pages. Edge functions improve app performance by reducing request latency and improving response times. With the release of Prisma v5.11.0, developers can now use Prisma ORM with their favorite Node.js database drivers in edge functions, and the query engine's size has been reduced to fit the limited runtime environment. If you want to understand what this exciting functionality brings as a whole, take a look at our blog post and go try it. 👉 Share your feedback with us via Twitter or Discord ## Performance improvements in nested create operations With Prisma ORM, you can create multiple new records in nested queries, for example: In previous versions, Prisma ORM would translate this into multiple SQL INSERT queries, each requiring its own roundtrip to the database. As of this release, these nested create queries are optimized and the INSERT queries are sent to the database in bulk in a single roundtrip. 👉 Read more in our 5.11.0 release notes. ## Join the Prisma Partner Network At Prisma, we deeply value the talented creators, educators, and builders in our community and we’ve long wanted to reward their contributions. We’re excited to launch the Prisma Partner Network with tailored opportunities for affiliates, tech partners, and resellers. 👉 prisma.io/partners ## Made with Prisma In our real-world interview series, we talk with founders who developed OSS projects using Prisma. Explore our recent chats: 🎥 Umami - The open source Google Analytics alternative Did you ever feel that Google Analytics is too bloated and that its UI and workflows are too complex? Discover how Umami offers a simple yet powerful alternative analytics tool. 🎥 Dub.co: Aiming for a billion with Prisma Steven Tey shares his journey from leaving Vercel to launching his startup. Learn how Dub.co began as a passion project, its technology stack, and an in-depth look at its codebase. --- ## [Prisma Client - Auto-generated query builder for your data](/client) **Meta Description:** Prisma is a next-generation ORM that can be used to build GraphQL servers, REST APIs, microservices & more. **Content:** ## Intuitive database client for TypeScript and Node.js The Prisma Client works seamlessly across languages and databases. Ship faster by writing less SQL. Avoid mistakes with a fully type-safe API tailored specifically for your app. ## Explore the Prisma Client API From simple reads to complex nested writes, the Prisma Client supports a wide range of operations to help you make the most of your data. ## Autocomplete your way to Success The best code is the code that writes itself. Prisma Client gives you a fantastic autocomplete experience so you can move quickly and be sure you don't write an invalid query. Our obsession with type safety means you can rest assured that your code works as expected, every time. ## Fully type-safe raw SQL Execute SQL queries directly against your database without losing the benefits of Prisma’s type-checking and auto-completion. TypedSQL leverages the capabilities of Prisma Client to write raw SQL queries that are type-checked at compile time. ## Works with your favourite databases and frameworks ## Supported Databases ## Selected Frameworks Easy to integrate into your framework of choice, Prisma simplifies database access, saves repetitive CRUD boilerplate and increases type safety. ## Visual database browser Prisma Studio is the easiest way to explore and manipulate data in your Prisma projects. Understand your data by browsing across tables, filter, paginate, traverse relations and edit your data with safety. ## Hassle-free migrations Prisma Migrate auto-generates SQL migrations from your Prisma schema. These migration files are fully customizable, giving you full control and ultimate flexibility — from local development to production environments. --- ## [Prisma & CockroachDB | ORM for the cloud-distributed database](/cockroachdb) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build applications with CockroachDB. **Content:** ## Distributed data andpowerful tooling withPrisma & CockroachDB Manage your data at scale with CockroachDB and Prisma – a next-generation ORM for Node.js and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and CockroachDB fit together CockroachDB is a relational, PostgreSQL wire-protocol-compatible database built for cloud applications and services. It automates the task of scale, so developers no longer have to choose between the data integrity offered by a relational database or the availability of NoSQL. And, when using CockroachDB developers don’t have to worry about deployment or ongoing administration/management of the database. Prisma is an open-source ORM that integrates seamlessly with CockroachDB and supports the full development cycle. Prisma helps you define your database schema declaratively using the Prisma schema and fetch data from CockroachDB with full type safety using Prisma Client.Together the two technologies give developers access to the scalable infrastructure of a distributed database without requiring them to be experts in hosting and scaling databases. ## Prisma Schema The Prisma schema uses Prisma's modeling language to define your database schema. It makes data modeling easy and intuitive, especially when it comes to modeling relations. Migrating your database schema is painless: you update the data model in your Prisma schema, run prisma db push to apply the schema changes, and CockroachDB will handle applying those changes to each database in your cluster. "CockroachDB and Prisma is a match made in heaven. Not only does it simplify data but it also eliminates database operations so you can focus on what you want to…your code." ## Why Prisma and CockroachDB? ## Zero downtime migrations CockroachDB clusters your databases into a single logical database, allowing it to apply schema migrations incrementally. ## Introspection & optimization tools Introspection allows you to pull down and easy-to-read representation of your database's schema. Here you have the ability to view and modify your indexes. ## Deploy to multiple cloud providers CockroachDB multi-cloud deployments allow you to avoid cloud-specific outages by deploying your database cluster to multiple providers at once. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Referential integrity with serverless CockroachDB's distributed data model allows you to manage your relational data as if it were in a single logical database. ## Intuitive data modeling Prisma's modeling language is declarative and lets you intuitively describe your database schema. ## Prisma support for CockroachDB is production ready In this article, we announce the general availability of the Prisma CockroachDB connector and take a look at some of the reasons why you should use Prisma and CockroachDB together. ## How Tryg has leveraged Prisma to democratize data How Tryg transforms billions of records from different data sources, and expose a single data model via GraphQL and Prisma. ## Featured Prisma & CockroachDB resources This section of the docs covers the details of Prisma's CockroachDB data source connector. In this section of the docs, you will learn about the concepts behind using Prisma and CockroachDB, the commonalities and differences between CockroachDB and other database providers, and the process for configuring your application to integrate with CockroachDB. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Community | Prisma](/community) **Meta Description:** Have a question, idea, or contribution for the Prisma ORM? You are not alone! Join hundreds of thousands of Prisma developers. **Content:** ## Join the growing Prisma Community Get the latest releases and product updates, tutorials, events, and more delivered to your inbox monthly. ## Connect with Prisma ## Here's a starter kit Explore our tutorials to build web apps using Prisma and Next.js, Remix, GraphQL, NestJS & more. Learn how to get started with Prisma from scratch. Explore how to use Prisma with our ready-to-run Prisma example projects. ## Livestreams, tutorials & tech talks Check out the Prisma YouTube channel for new videos, live streams, and meetups with Prisma folks and audience members. It covers topics like TypeScript, Node.js, databases, and news from the Prisma ecosystem. ## Join us for regular meetups and events ## Prisma Meetup Discuss the latest database and API developments and learn more about Prisma's best practices. ## GraphQL Meetup Join speakers from all around the globe to learn about the latest news in the GraphQL world. ## TypeScript Meetup Share knowledge, discover use cases, and real problems (and solutions) using TypeScript. ## Contributing to Prisma We welcome contributions of all forms from experienced developers and beginners alike. Showcase your projects, share your ideas, or help us improve Prisma with your feedback! Share your feedback about our Open Source Have you built a custom middleware or generator? Get support from our team Contribute to our Docs --- ## [Prisma Data Proxy](/data-platform/proxy) **Meta Description:** Prisma Data Proxy was an external connection pool that helped scale database connections in Serverless environments. **Content:** ## Prisma Data Proxy Prisma Data Proxy was a managed connection pool service that helped scale database connections in serverless environments. ## What’s next? As an evolution of Data Proxy, Prisma Accelerate introduced a range of improvements and new features, including more robust and performant connection pooling, as well as global caching for database queries. --- ## [Prisma Day 2022 | Covid Accessibility](/day/covid-accessibility) **Meta Description:** Prisma Day is a two-day hybrid event of talks and workshops about modern application development and databases, featuring and led by members of the Prisma community. Prisma Day 2022 will happen from June 15-16th, both in-person and online. **Content:** ## Covid & Accessibility ## Covid policy ## Venue In the interest of everyone’s safety and comfort, our in-person conference day will take place outdoors. 🌳🌳🌳 ## Vaccination This will be a 3G (*geimpft, getestet, genesen*) event, meaning all attendees should be: Fully vaccinated; recovered (if exposed to or ill with COVID in the last 90 days); and/or have proof of a negative test (from within 24 hours of the event). During registration, you will be asked to share some form of proof that shows you fall into one of these categories. ## Masks Masks are not required but are certainly welcome! We recommend FFP2/KN95 or OP masks ## Refunds in case of symptoms In the interest of public safety, if you are not feeling well or are exhibiting symptoms, we ask that you do not attend  Prisma Day’s in-person events. (In the event of illness, please reach out to Irena and let us know that you cannot attend. We’ll refund your ticket, and you’ll still be able to access the conference remotely!) ## Accessibility features ## In person For those attending in person, here are a few details about the James June Sommergarten location: ## Online For those accessing Prisma Day events remotely, closed-captioning services will be available for all recorded video content, in the days following the conference. 📺 --- ## [Prisma Day 2022 | Speakers](/day/speakers) **Meta Description:** Prisma Day is a two-day hybrid event of talks and workshops about modern application development and databases, featuring and led by members of the Prisma community. Prisma Day 2022 will happen from June 15-16th, both in-person and online. **Content:** ## Our line-up of speakers ## Alberto Schiabel ## Senior Software Engineer @ Prisma Alberto is a senior software engineer and former startup co-founder. He has 7+ years of experience, and he's into typed functional programming. He's currently a part of the Schema Team at Prisma. ## Aleksandra Sikora ## Lead Blitz.js Maintainer @ Aleksandra is a full-stack developer passionate about TypeScript, web technologies and databases. She was previously a tech lead for the Hasura Console, and now she's a lead maintainer of Blitz.js. ## Alex Ruheni ## Developer Advocate @ Prisma Alex is a Developer Advocate at Prisma, where he's working to make databases easy and fun. He loves learning and teaching other developers. In his free time, he enjoys photography. ## Amy Dutton ## Director of Design @ ZEAL Amy loves using her 20 years of internet experience to teach developers how to design, and designers how to develop. She lives in Nashville, TN USA with her husband, 3 adorable kids, and 2 dogs. ## Chance Strickland ## Software Engineeer @ Remix Chance Strickland is a software engineer at Remix and the maintainer of Reach UI. He previously worked on Radix UI at Modulz and has taught hundreds of developers leading workshops at React Training. ## David Price ## Cofounder @ RedwoodJS David is a cofounder of RedwoodJS, the full-stack app framework for startups. His favorite things in life, in ascending order, are ethics, entrepreneurial leadership, collaboration, and his family. ## Delba de Oliveira ## Developer Advocate @ Vercel Delba is interested in helping developers build great web applications. She’s a hobbyist videographer and Senior Developer Advocate at Vercel; where she creates educational content by combining her love for video and code. ## Hassan Bazzi ## Cofounder @ Nuna.ai Hassan is a people-oriented engineering leader. He builds teams with a core DNA of compassion and autonomy, and loves to code in all parts of the stack. Passionate about space, nature, and philosophy. ## Jesse Hall ## Senior Developer Advocate @ MongoDB Jesse Hall, aka codeSTACKr, is a full-stack, self-taught developer with a passion to educate others about all things coding related. His favorite topics are JavaScript, React, CSS, and of course MongoDB. ## Josh Goldberg ## Open Source Developer @ Josh is an open source developer from New York with passion for accessibility and static analysis. He works in the TypeScript ecosystem and published a Learning TypeScript book with O'Reilly. ## Liz van Dijk ## Solution Architect @ Planetscale Liz has been active as a consultant and solution architect in the MySQL Scalability world for the past decade. ## Lucy Keer ## Technical Writer @ Prisma Lucy is a technical writer at Prisma. She previously worked as a software developer and enjoys combining these skills to find ways to explain technical topics clearly. ## Michael Hayes ## Staff Engineer @ The Trade Desk Michael is a developer with a passion for developer tools. He has worked on tracing at New Relic, node infrastructure at Airbnb, and is now focusing on open source tooling for type-safe GraphQL ## Nikita Shamgunov ## CEO @ Neon Nikita is a Founder of Neon - serverless Postgres. Nikita also is a Partner at Khosla Ventures. He is passionate about deep tech, data infrastructure, and system software. ## Nikolas Burk ## Developer Advocate @ Prisma Nikolas is passionate about teaching and sharing knowledge. He has been with Prisma since the early days and loves to connect with the Prisma community! ## Nilufar Bava ## Web Developer @ Prisma Nilufar is a web developer with over of a decade of experience in several web, native and hybrid frameworks. She has been leading the web development in Prisma for the past couple of years. ## Olivier Falardeau ## Head of Engineering @ oxio Oli is a full-stack developer from Quebec with a passion for distributed systems and trading. He worked in machine learning at Rakuten and is now focused on building legendary engineering teams. ## Søren Bramer Schmidt ## Co-founder @ Prisma Søren is Chief Architect and Co-Founder of Prisma, building the data platform for modern applications. Before founding Prisma, he lead a team-building foundational infrastructure for Trustpilot. ## Tasin Ishmam ## Developer Advocate @ Prisma Tasin is a Developer Advocate at Prisma. He loves geeking out about technology and traveling; sometimes, both those things at once! --- ## [Prisma Day 2022 | Talks](/day/talks) **Meta Description:** Prisma Day is a two-day hybrid event of talks and workshops about modern application development and databases, featuring and led by members of the Prisma community. Prisma Day 2022 will happen from June 15-16th, both in-person and online. **Content:** Co-founder Prisma ## Keynote Developer Advocate Vercel ## From table to pixel. The journey of your data with React, Next.js, and Prisma React is changing the way we think about routing, rendering, and fetching in web applications. Features like React Server Components and Suspense can give us more granular control of when and where to fetch and render content for our routes. In this talk, we’ll explore how everything connects; and how React, Next.js, and Prisma makes it easier to manage the journey of your data, from table to pixel in just one repo. Senior Developer Advocate MongoDB ## Think like a document - Structuring data in documents vs tables Structuring data as normalized is the standard for relational databases. But who wants to be normal?? Let’s de-normalize our data, put it in documents, and get lightning fast reads in our applications! In this talk, you’ll learn different methods of storing data in a document database like MongoDB. There are tradeoffs between normalization and denormalization. One will give you faster reads but slower writes, and the other will get you slower reads and faster writes. Which is right for you? By the end of this talk, you’ll know! Staff Engineer The Trade Desk ## Pothos + Prisma: Delightful, type-safe, and efficient GraphQL Learn how Pothos and Prisma can create a delightful developer experience for building type-safe GraphQL APIs with great performance and type-safety without sacrificing flexibility and control over your API, or closely coupling your API to your database schema. Cofounder Nuna.ai ## Serverless heaven Together, we will dive into how we've used serverless technologies at Nuna to scale infinitely. We use the power of Prisma Data Proxy to talk to our serverless MongoDB database through our serverless NextJS API. And if our small team can do it, so can you! Head of Engineering oxio ## Using Prisma to connect any Canadian household to the Internet The fixed-line Internet landscape in Canada is... not optimal. Competition is scarce, prices are high for average speeds and the NPS score in the industry is embarrassing. Now, what if I told you that modern web technologies, like GraphQL, Prisma, TypeScript, and a handful of developers can be a game-changer in this dreaded sector? Open Source Developer ## Adventures in type safe Prisma Clients Prisma generates fantastic TypeScript types for clients. They include type system features such as conditional and mapped types to give precise types for the results of client method calls. This talk will cover how those foundational types work in TypeScript and the ways Prisma uses them. We'll also cover how to use them to extend Prisma's types for wrapper functions and other shenanigans I've seen consumers of Prisma need. Web Developer Prisma Technical Writer Prisma ## How we make Prisma Docs effective and engaging When Prisma releases new features, how do we make sure everyone can learn about them? In this talk, we’ll cover how Prisma’s docs and website teams work together with developers and the community to create our documentation. Senior Software Engineer Prisma ## Things about Prisma VS Code extension that just make sense Director of Design ZEAL ## How Redwood and Prisma make frontend developers fullstack Backend technology is often elusive and an obstacle for frontend developers. The strategic pairing (Frontend to Fullstack), however, is where the magic happens. A solid backend makes the frontend “smart” and truly shine. Tooling, like Redwood and Prisma, helps developers leverage full-stack capabilities, allowing teams to build faster and more efficiently, connecting critical front and backend user experiences. “How to go Frontend to Fullstack with Redwood and Prisma” will demonstrate how critical backend technologies are approachable and easy to learn, even for frontend engineers. Developers knowledgeable in JavaScript already have everything they need to be successful. It’s simply a matter of putting the pieces together by leveraging the right tech and platform combinations. In preparation for this talk, I will create a demo with all the frontend code needed for a full-stack, web application. I will demonstrate how easy it is to build out the project and connect the backend layer, using tools like Redwood and Prisma. CEO Neon ## Introducing Neon - the serverless Postgres built for the cloud Databases are foundational machinery in modern society. Mission-critical applications are built on Postgres and the Postgres community continues to strengthen Postgres to meet real-world demands. We believe Postgres will remain one of the most important (open-source) relational databases of our time. Neon is a serverless implementation of PostgreSQL. It’s an auto-scaling, on-demand database as a service for modern applications, making it a credible open-source alternative to Amazon Aurora. Neon’s key innovation is separation of storage and compute which makes Postgres cloud native and serverless. This allows for several advantages: Neon reduces the complexity involved in provisioning and managing database capacity, and scales up to support large databases or scales down when the database is not needed. Additionally, it allows efficient management of database resources. Solution Architect Planetscale ## Developer-owned databases: A new frontier? Developers don't always tend to have the healthiest relationship with their databases. Design choices that, early on, can feel unimportant, tend to grow into monstrous scalability challenges down the line, and entire families of technologies have sprung up around the ability to avoid ever having to make changes to an old, inefficiently designed schema. But why do we keep falling into the same traps, and how can we avoid them? This talk will cover some of the key points to pay attention to in early relational database design, share some war stories around scaling up, and arm you with the knowledge and tools to designing a database that will scale along with your application's success. Lead Blitz.js Maintainer ## SQL tricks and concepts you didn't know about Did you know that some SQL variants are Turing complete and let you write any program in SQL? Of course, no one's that crazy... But what are the limits of SQL? What are some crazy things we can do with it? I'm going to go over a few of them in this talk. It won't be only fun stuff, though! I'm going to show some more practical but lesser-known concepts too. Let's discover some hidden SQL traits together! Developer Advocate Prisma ## A glimpse into the future of Prisma Prisma has seen rapid adoption in the developer community! We are excited about this and want to continue building world-class developer tools that make it easier for developers to work with databases. In this talk, you will see what kind of features we have on the roadmap for 2022 and beyond. --- ## [Prisma Day 2022 | Workshops](/day/workshops) **Meta Description:** Prisma Day is a two-day hybrid event of talks and workshops about modern application development and databases, featuring and led by members of the Prisma community. Prisma Day 2022 will happen from June 15-16th, both in-person and online. **Content:** Developer Advocate Prisma ## Introduction to Prisma Prisma is an open-source ORM for Node.js and TypeScript. In this workshop, you’ll learn the fundamentals of using Prisma and practice various workflows, from modelling data, to performing database migrations, to querying the database to read and write data. You’ll also learn how Prisma fits into your application stack by integrating in a REST and a GraphQL API using a SQLite database. Developer Advocate Prisma ## Deep dive into database workflows with Prisma Prisma is an open-source ORM for Node.js and TypeScript. By the end of this workshop, you will learn how to work with features such as schema prototyping with Prisma Migrate, working with database native types, how to use Prisma Migrate in your development and CI/ CD environment, and build workflows using the-lesser-known features of Prisma Migrate. Developer Advocate Prisma ## Let’s build a REST API with NestJS and Prisma! NestJS is one of the hottest Node.js frameworks around. In this workshop, you will learn how to build a backend REST API with NestJS, Prisma, PostgreSQL and Swagger. Software Engineeer Remix ## Update while you wait: Optimistic UI with Remix and Prisma Learn to build state-of-the-art, highly responsive user interfaces with Remix and Prisma. This workshop focuses on the pattern of optimistic updates, teaching you how to use the best of both tools to build interactions that feel instantaneous to users.At the end of this workshop, you’ll know how to: • Reduce latency and remove loading spinners for a snappier user experience • Use more advanced Remix tools like useFetcher • Gracefully handle errors • Optimize requests with Prisma’s functional API and Remix’s loaders and actions --- ## [Prisma Day 2019 | Conference on databases & application development](/day-2019) **Meta Description:** Prisma Day is a one day, single-track conference in Berlin focused on databases and application development. **Content:** ## Prisma Day 2019 The data and application development space is rapidly evolving and developers have access to an expanding array of data tooling to choose from. Prisma Day will detail the most interesting techniques and tools in the space, as well give the context and background on what exactly makes these new approaches so useful. Prisma Day, additionally, seeks to offer best practices and practical information across different tools and use-cases. By bringing together experts in the database field and developers interested in the latest workflows and tooling, Prisma Day will give a deep introduction to modern approaches for managing application data. --- ## [Prisma Day 2020 | Modern Application Development and Databases](/day-2020) **Meta Description:** A one day, single-track conference on modern application development and databases. Learn from database and application engineering leaders in an interactive online event. **Content:** ## Prisma Day JUNE 25 / 26 WATCH THE TALKS BELOW A Day for the Prisma Community! It's a packed event for devs seeking to understand how to best work with data in the modern application stack. But this conference is far more than just the talks! Join the Prisma Showcase Lightning talks on the amazing tools and products being built by the Prisma Community! Engage in a Q&A with speakers Dive deeper into talks and learn directly from top experts. Learn more! Choose from a workshop on Prisma or on Prisma with GraphQL or Next for a detailed guide on Prisma usage. ## Topics to be discussed Modern Application Development From type safety and TypeScript, or GraphQL, or JAMStack and the latest Javascript Frameworks, get an overview of the evolving tool landscape that reshapes how applications are architected, built, and deployed. Database best practices A deeper dive into considerations when building stateful application. Discover the key considerations that give you further control over getting the most out of your data. The Prisma Ecosystem From best practices to adoption strategies to Prisma in production environments, learn how Prisma supports developers throughout their development process. June 25 ## Workshops Sign up in advance for the workshop you want to join! ## A practical introduction to Prisma 2.0 ## Building a type-safe GraphQL server with Nexus and Prisma ## Building static sites with Prisma and Next.js June 26 ## Talks Great talks with interactive Q&A. No signup required! ## Welcome ## Keynote ## Prisma 2.0: Productivity and Confidence for your database ## Happy Table Friends: Relations in Prisma ## Welcome to Part 2 ## Data Discovery with Studio ## Showcase: Building a Calendar App with Prisma ## Serverless Prisma 2 with GCP Cloud Run ## Welcome to Part 3 ## How Prisma Solves the N+1 Problem in GraphQL Resolvers ## Showcase: Prisma Admin React Component ## Prisma VSCode Extension ## Type-Safety Beyond TypeScript ## Showcase: Accessing Databases using NestJS with Prisma ## Welcome to Part 4 ## RedwoodJS: Bringing Full-Stack to the Jamstack ## Blitz: the Full-Stack React Framework ## The Jamstack and Your Data ## Closing Expert Speakers Tom Preston-Werner Founder @ Redwoodjs Mathias Biilmann Christensen CEO @ Netlify Martina Helene Welander Education Engineeer @ Prisma Søren Bramer Schmidt Co-founder @ Prisma Brandon Bayer Creator of Blitz.js Lee Robinson Software Engineer @ Hy-Vee Carmen Berndt Software Engineer @ Prisma Émile Fugulin Backend & DevOps Freelancer Siddhant Sinha Software Engineer @ Prisma Tim Suchanek Software Engineer @ Prisma Flavian Desverne Software Engineer @ Prisma Daniel Norman Developer Advocate @ Prisma Nikolas Burk Developer Relations @ Prisma Jason Kuhrt Software Engineer @ Prisma Joël Galeran TypeScript Developer @ Prisma Marc Stammerjohann Full-Stack Freelancer Ahmed Elywa Full-Stack Developer Warren Day Full-Stack Developer --- ## [Prisma Day 2021Prisma.io](/day-2021) **Meta Description:** Join us for Prisma Day 2021, Jun 29-30. An online two-day conference full of speakers and workshops for the prisma community. **Content:** ## Prisma Day Prisma Day is two day event of talks and workshops by members of the Prisma community, on modern application development and databases. Prisma Day 2021 happened on June 29-30th and was entirely online. ## Workshops Watch the workshops which took place for Prisma Day 2021 ## 실용적인 Prisma 예제 소개 ## A Practical Introduction to Prisma ## Building GraphQL APIs with Prisma ## Getting Started with Next.js and Prisma ## Building a REST API with NestJS and Prisma ## Building a TodoApp with Wasp - a DSL for building web apps (React, Node) with 10x less code ## Creating A User Dashboard with Redwood and Prisma ## Building a Node.js API with Prisma in minutes, using Amplication ## Introducing KeystoneJS, the CMS & API Platform for Prisma ## Build Fullstack Apps in Record Time with Blitz.js ## Talks Checkout the amazing talks we had. ## Opening Keynote ## The world's worst pool party: Connection management with Prisma ## Get a safe, minimized version of your production database on your laptop in minutes ## PlanetScale and Prisma: building in the cloud ## Prisma in Production Discussion Panel ## Democratizing data: Tryg & Prisma ## Real-time GraphQL APIs with Prisma and AWS AppSync ## Events at Prisma ## Next-gen CMS and GraphQL API with KeystoneJS and Prisma ## Prisma, Next.js & ISR: Building Speedy Web Apps ## Supercharge your Tests with Factories ## Using Prisma in a Full-Stack Redwood App ## Zero to App: IndieHacking a Jamstack SaaS ## Autogenerate GraphQL API from Prisma schema ## What's next for Prisma? ## Databases in the Jamstack ## Speakers ## Artur Mrozowski Artur is a data engineer & architect at Tryg. His motto is: functionality before technology. ## Carmen Berndt Carmen is a Computer Science Master student who worked at Prisma focusing on the code editor extensions streamlining the developer experience. Besides that, she's a horticulture enthusiast and buys at least 3 plants a week. ## Cassidy Williams Cassidy is a Principal Developer Experience Engineer at Netlify. She's active in the developer community, and one of Glamour Magazine's 35 Women Under 35 Changing the Tech Industry and LinkedIn's Top Professionals 35 & Under. She loves mechanical keyboards and karaoke. ## Chris Ball Chris is CTO & Co-Founder at Echobind, a full-service agency specializing in Next.js, React, React Native, GraphQL, and Node. When he's not helping developers grow or creating amazing products for clients, you're likely to find him playing guitar, cycling, or camping. ## Émile Fugulin Emile is a backend and devops freelancer. He helps enterprises build products using the latest practices like GraphQL and Infrastructure as Code. He has been using Prisma 2 in production for almost two years and has been an active member and contributor to the Prisma project and community. ## Eve Porcello Eve Porcello is a software engineer, instructor, author, and co-founder of Moon Highway. Her career started writing technical specifications and creating UX designs for web projects. Since starting Moon Highway in 2012, she has created video content for egghead.io and LinkedIn Learning and has co-authored Learning React and Learning GraphQL for O'Reilly Media. She is also a frequent conference speaker and has presented at conferences including React Rally, GraphQL Summit, and OSCON. --- ## [Prisma Day 2022](/day) **Meta Description:** Prisma Day is a two-day hybrid event of talks and workshops about modern application development and databases, featuring and led by members of the Prisma community. Prisma Day 2022 will happen from June 15-16th, both in-person and online. **Content:** Thank you for attending Prisma Day 2022! Recordings from our events are now available. Feel free to rewatch, relearn, and re-enjoy! ## Gallery ## Conference Talks & Workshops Co-founder Prisma ## Keynote Developer Advocate Vercel ## From table to pixel. The journey of your data with React, Next.js, and Prisma React is changing the way we think about routing, rendering, and fetching in web applications. Features like React Server Components and Suspense can give us more granular control of when and where to fetch and render content for our routes. In this talk, we’ll explore how everything connects; and how React, Next.js, and Prisma makes it easier to manage the journey of your data, from table to pixel in just one repo. Senior Developer Advocate MongoDB ## Think like a document - Structuring data in documents vs tables Structuring data as normalized is the standard for relational databases. But who wants to be normal?? Let’s de-normalize our data, put it in documents, and get lightning fast reads in our applications! In this talk, you’ll learn different methods of storing data in a document database like MongoDB. There are tradeoffs between normalization and denormalization. One will give you faster reads but slower writes, and the other will get you slower reads and faster writes. Which is right for you? By the end of this talk, you’ll know! Staff Engineer The Trade Desk ## Pothos + Prisma: Delightful, type-safe, and efficient GraphQL Learn how Pothos and Prisma can create a delightful developer experience for building type-safe GraphQL APIs with great performance and type-safety without sacrificing flexibility and control over your API, or closely coupling your API to your database schema. Cofounder Nuna.ai ## Serverless heaven Together, we will dive into how we've used serverless technologies at Nuna to scale infinitely. We use the power of Prisma Data Proxy to talk to our serverless MongoDB database through our serverless NextJS API. And if our small team can do it, so can you! Head of Engineering oxio ## Using Prisma to connect any Canadian household to the Internet The fixed-line Internet landscape in Canada is... not optimal. Competition is scarce, prices are high for average speeds and the NPS score in the industry is embarrassing. Now, what if I told you that modern web technologies, like GraphQL, Prisma, TypeScript, and a handful of developers can be a game-changer in this dreaded sector? Open Source Developer ## Adventures in type safe Prisma Clients Prisma generates fantastic TypeScript types for clients. They include type system features such as conditional and mapped types to give precise types for the results of client method calls. This talk will cover how those foundational types work in TypeScript and the ways Prisma uses them. We'll also cover how to use them to extend Prisma's types for wrapper functions and other shenanigans I've seen consumers of Prisma need. Web Developer Prisma Technical Writer Prisma ## How we make Prisma Docs effective and engaging When Prisma releases new features, how do we make sure everyone can learn about them? In this talk, we’ll cover how Prisma’s docs and website teams work together with developers and the community to create our documentation. Senior Software Engineer Prisma ## Things about Prisma VS Code extension that just make sense Director of Design ZEAL ## How Redwood and Prisma make frontend developers fullstack Backend technology is often elusive and an obstacle for frontend developers. The strategic pairing (Frontend to Fullstack), however, is where the magic happens. A solid backend makes the frontend “smart” and truly shine. Tooling, like Redwood and Prisma, helps developers leverage full-stack capabilities, allowing teams to build faster and more efficiently, connecting critical front and backend user experiences. “How to go Frontend to Fullstack with Redwood and Prisma” will demonstrate how critical backend technologies are approachable and easy to learn, even for frontend engineers. Developers knowledgeable in JavaScript already have everything they need to be successful. It’s simply a matter of putting the pieces together by leveraging the right tech and platform combinations. In preparation for this talk, I will create a demo with all the frontend code needed for a full-stack, web application. I will demonstrate how easy it is to build out the project and connect the backend layer, using tools like Redwood and Prisma. CEO Neon ## Introducing Neon - the serverless Postgres built for the cloud Databases are foundational machinery in modern society. Mission-critical applications are built on Postgres and the Postgres community continues to strengthen Postgres to meet real-world demands. We believe Postgres will remain one of the most important (open-source) relational databases of our time. Neon is a serverless implementation of PostgreSQL. It’s an auto-scaling, on-demand database as a service for modern applications, making it a credible open-source alternative to Amazon Aurora. Neon’s key innovation is separation of storage and compute which makes Postgres cloud native and serverless. This allows for several advantages: Neon reduces the complexity involved in provisioning and managing database capacity, and scales up to support large databases or scales down when the database is not needed. Additionally, it allows efficient management of database resources. Solution Architect Planetscale ## Developer-owned databases: A new frontier? Developers don't always tend to have the healthiest relationship with their databases. Design choices that, early on, can feel unimportant, tend to grow into monstrous scalability challenges down the line, and entire families of technologies have sprung up around the ability to avoid ever having to make changes to an old, inefficiently designed schema. But why do we keep falling into the same traps, and how can we avoid them? This talk will cover some of the key points to pay attention to in early relational database design, share some war stories around scaling up, and arm you with the knowledge and tools to designing a database that will scale along with your application's success. Lead Blitz.js Maintainer ## SQL tricks and concepts you didn't know about Did you know that some SQL variants are Turing complete and let you write any program in SQL? Of course, no one's that crazy... But what are the limits of SQL? What are some crazy things we can do with it? I'm going to go over a few of them in this talk. It won't be only fun stuff, though! I'm going to show some more practical but lesser-known concepts too. Let's discover some hidden SQL traits together! Developer Advocate Prisma ## A glimpse into the future of Prisma Prisma has seen rapid adoption in the developer community! We are excited about this and want to continue building world-class developer tools that make it easier for developers to work with databases. In this talk, you will see what kind of features we have on the roadmap for 2022 and beyond. Developer Advocate Prisma ## Introduction to Prisma Prisma is an open-source ORM for Node.js and TypeScript. In this workshop, you’ll learn the fundamentals of using Prisma and practice various workflows, from modelling data, to performing database migrations, to querying the database to read and write data. You’ll also learn how Prisma fits into your application stack by integrating in a REST and a GraphQL API using a SQLite database. Developer Advocate Prisma ## Deep dive into database workflows with Prisma Prisma is an open-source ORM for Node.js and TypeScript. By the end of this workshop, you will learn how to work with features such as schema prototyping with Prisma Migrate, working with database native types, how to use Prisma Migrate in your development and CI/ CD environment, and build workflows using the-lesser-known features of Prisma Migrate. Developer Advocate Prisma ## Let’s build a REST API with NestJS and Prisma! NestJS is one of the hottest Node.js frameworks around. In this workshop, you will learn how to build a backend REST API with NestJS, Prisma, PostgreSQL and Swagger. Software Engineeer Remix ## Update while you wait: Optimistic UI with Remix and Prisma Learn to build state-of-the-art, highly responsive user interfaces with Remix and Prisma. This workshop focuses on the pattern of optimistic updates, teaching you how to use the best of both tools to build interactions that feel instantaneous to users.At the end of this workshop, you’ll know how to: • Reduce latency and remove loading spinners for a snappier user experience • Use more advanced Remix tools like useFetcher • Gracefully handle errors • Optimize requests with Prisma’s functional API and Remix’s loaders and actions --- ## [Prisma ORM Ecosystem](/ecosystem) **Meta Description:** Explore the variety of tools (from generators, to middleware, to CLIs) created by the Prisma community. **Content:** ## Prisma Ecosystem Explore the wide variety of tools created by our amazing community. ## Packages to supercharge your developement with Prisma From custom generators, to middleware, to CLIs — these packages will improve your life when working with Prisma. ## Generators Transforms the Prisma schema into Database Markup Language (DBML) which allows for an easy visual representation Generates an individual API reference for Prisma Transforms the Prisma schema in JSON schema Generates TypeGraphQL CRUD resolvers for Prisma models Generates TypeGraphQL class types and enums from your Prisma type definitions; the generated output can be edited without being overwritten by the next gen and has the ability to correct you when you mess up the types with your edits. Generates object types, inputs, args, etc. from the Prisma schema file for usage with @nestjs/graphqlmodule Generates object types, inputs, args, etc. from the Prisma schema file for usage with @nestjs/graphqlmodule Generates DTO and Entity classes with relation connect and createoptions for use with NestJS Resources and @nestjs/swagger Generates an entity relationship diagram Generates classes from your Prisma Schema that can be used as DTO, Swagger Response, TypeGraphQL, and so on. Generate full Joi schemas from your Prisma schema. Generate full Yup schemas from your Prisma schema. Emit TypeScript models from your Prisma schema with class validator validations ready. Emit Zod schemas from your Prisma schema. Emit fully implemented tRPC routers. Emit a JSON file that can be run with json-server Emit a tRPC shield from your Prisma schema. Everything you need to build your Prisma generator like an elite open-source maintainer A generator, which takes a Prisma 2 schema.prisma and generates a JSON Schema in flavor which MongoDB accepts Merge multiple files, create model inheritance and abstraction and create cross-file relations. Additionally, generate schemas using code, configure your data source using YAML and XML and more. ## Middleware This is a Prisma middleware used for caching and storing of Prisma queries in Redis (uses an in-memory LRU cache as fallback storage). With this middleware you can cache your database queries into the Redis (one of the fastest in-memory databases for caching) and reduce your database queries. A declarative authorisation middleware that operates on Prisma model level (and not on GraphQL resolver level). A slugification middleware for Prisma. It generates slugs for your models by using other model attributes with logic that you can define. ## Other Creates Zod schemas from your Prisma models. Makes it easier to define Prisma-based object types, and helps solve n+1 queries for relations. It also has integrations for the Relay plugin to make defining nodes and connections easy and efficient. This package provides you with Prisma Client Provider and Auth Provider for working with Prisma and Adonis.js Dispatches several types of events while working with Prisma models. EventEmitter agnostic, and allows you to choose for what kind of models, actions and moment of lifecycle to emit the events, configure your data source using YAML and XML and more. Open-source, low-code framework that accelerates the development of admins, dashboards, and B2B apps. A simple and type-safe mocking utility for Prisma Client in Bun tests. --- ## [Prisma Enterprise Event 2021](/enterprise-event-2021) **Meta Description:** An online conference focused on the challenges large companies and enterprises face with the management of application data. **Content:** ## Prisma Enterprise  Event An online conference focused on the challenges large companies and enterprises face with the management of application data. ## March 25th 2pm CET / 9am EDT A particular focus of the event will be the migration of data across different data sources and making data accessible to teams across an organization. ## About the event The technical needs of companies and enterprises are evolving and changing. Technologies like TypeScript speed up developer productivity and enable companies to move faster than ever in creating new products. Team buy-in, new workflows, different deployment paradigms, changes around the maintenance of applications and their data, are considerations that evolve at a fast pace. Learn how top companies are addressing the challenges of data at scale Discover how companies use Prisma to make their developers more productive Get a better understanding of the future of data in the enterprise ## Schedule ## Welcome ## Opening Keynote ## Cloud Native Data: The Emergence of Enterprise Data Fabrics An overview of how the enterprise data landscape is changing. ## Prisma at Rapha How Prisma helps Rapha unify data access from multiple enterprise systems into a single API. ## Prisma Enterprise Demo ## Prisma Fireside Chat Answering all your burning questions ## Building Products That Scale Learn what breaks at scale, what you should know beforehand, and the hard-won lessons from internet giants like Google. ## Developer Experience Matters How a thoughtful developer experience can unlock productivity for your customers and internal teams. ## Tearing Down Data Silos How data silos emerge, the need for connecting data, and Prisma's vision of the Application Data Platform. ## The Evolution of Application Data Platforms – From Facebook to Twitter How Twitter and Facebook move faster than the industry average while running a platform with millions of users ## Closing Keynote ## Office Hours Learn more about using Prisma in your organization! Sign up for office hours with key leaders at Prisma to dive into your specific questions. ## Søren Bramer Schmidt Chief Executive Officer ## Hervé Labas VP of Product ## Chris Matteson Head of Solutions Engineering ## Speakers Learn more about the technologies and approaches that enable enterprises to address the challenges of data at scale from experts in the field. ## James Governor Analyst and Co-founder @ Redmonk ## Tom Hutchinson Head of Mobile @ Rapha ## Hervé Labas VP of Product @ Prisma ## Natalie Vais Principal @ Amplify Partners ## Søren Bramer Schmidt CEO @ Prisma ## Chris Matteson Head of Solutions Engineering @ Prisma ## Pete Hunt Software Engineer @ Twitter ## DeVaris Brown CEO and Founder @ Meroxa ## Vladi Stevanovic Customer Success Manager @ Prisma ## Who is attending This is an event for anyone interested in using Prisma in a team or at scale. We'll be inviting engineering leaders from companies ranging from startups to larger corporations. This event will be especially relevant to tech leads eager to learn more about new technical approaches and begin advocating for changes on a wider level. --- ## [Streamline your enterprise development workflow with Prisma](/enterprise) **Meta Description:** Learn how Prisma ORM can improve your team's productivity and explore our tailored ORM support solutions for enterprises and solution providers. **Content:** ## Streamline your development workflow Prisma acts as your comprehensive enterprise data toolset, simplifying database interactions and reducing complexity so developers can focus on business logic. ## Boost your application’s lifecycle ## Boost your application’s lifecycle By integrating Prisma into your development ecosystem, you leverage its capabilities to Build robust, adaptable applications with less code and fewer errors and also Fortify your database interactions for peak performance right from the start.As your application Grows, our platform products Accelerate and Prisma Postgres ensure that your data layer can adapt and scale, supporting increased traffic and requirements without sacrificing performance or security. ## Leave the database complexities to us Focus on core competencies of your team, rather than building and managing complex infrastructure components. ## Improved developer experience Prisma ORM enhances code clarity and modularity. New team members can onboard quickly, thanks to the high level of abstraction and the intuitive query syntax. ## Increased productivity The Prisma ORM Client API comes with an intuitive querying interface and editor auto-completion, allowing developers to focus on business logic instead of database syntax. ## Bring your own database Prisma ORM’s extensive compatibility enables teams to work with different databases and switch without significant changes to the application logic. ## Development efficiency ## Abstraction and ease of use Prisma ORM allows developers to work with high-level objects and methods instead of raw SQL queries. This accelerates development and minimizes errors associated with directly handling SQL. Retrieving user data can be as straightforward as prisma.user.findMany() insteadof constructing a complex SQL query. ## Database schema migration Prisma Migrate facilitates easy version control for database schemas, streamlining the deployment and rollback of changes. This is crucial for maintaining consistency across environments. The schema evolution necessary for application development becomes safe and hassle-free, yet customizable to provide flexibility. ## Reduced training needs By standardizing database interactions, Prisma ORM reduces the need for in-depth database-specific training. New team members can contribute quickly, focusing on learning your data model rather than the nuances of SQL. ## Transferability 
of responsibilities The uniform interface provided by Prisma ORM simplifies the transfer of responsibilities within the team. Developers can easily understand and work on different parts of the application, enhancing team flexibility and resilience. ## Improved productivity The Prisma ORM Client API boosts developer productivity by providing a querying interface that is intuitive and comes with features like editor auto-completion. This reduces the cognitive load on developers, allowing them to focus on business logic rather than database syntax intricacies. ## Cross-functional team collaboration Prisma ORM’s schema-centric approach enhances collaboration between developers and database administrators (DBAs) by providing a clear, version-controlled schema definition. This shared understanding facilitates smoother communication and decision-making. ## Improved developer experience Prisma ORM contributes to a more modular and understandable codebase, significantly enhancing developer experience. The modularity facilitates easier testing and debugging, as developers can focus on smaller, more isolated parts of the application logic. ## Code quality and safety With Prisma ORM’s first-class TypeScript support, developers benefit from compile-time type checking, significantly reducing runtime errors. Any changes in the database schema are reflected in the code, prompting immediate updates where necessary. With Prisma ORM’s first-class TypeScript support, developers benefit from compile-time type checking, significantly reducing runtime errors. Any changes in the database schema are reflected in the code, prompting immediate updates where necessary. Prisma ORM mitigates common security vulnerabilities, such as SQL injection, by abstracting raw SQL queries and sanitizing inputs. This built-in protection layer adds an additional security safeguard for applications. While ORMs add a layer of abstraction, Prisma ORM is optimized to generate efficient SQL queries, minimizing performance overhead. Techniques such as query batching and selective loading of data ensure applications remain responsive and scalable. ## Scalability and portability ## Support for multiple databases Prisma ORM’s compatibility enables teams to work with different databases without significant changes to the application logic. Developers can easily switch between different projects, and applications can be easily adapted to future requirements without extensive rework. ## Community and ecosystem The vibrant Prisma community and ecosystem offer extensive resources, including documentation, tutorials, and support forums. This knowledge pool aids in resolving issues swiftly and exchanging best practices. ## Scalability at its core Designed with scalability in mind, Prisma products support efficient data fetching and manipulation patterns that are essential for high-load applications, ensuring that the database layer does not become a bottleneck as the application grows. ## Code maintainability The reduction in handwritten SQL leads to cleaner, more maintainable codebases. Developers can focus on the business logic rather than the intricacies of SQL syntax, making it easier to update and refactor code. ## Enterprises ## Solution Providers ## Comprehensive support solutions for your enterprise operations Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations. Ensuring that your use of the Prisma ORM complies with relevant standards, reducing legal and operational risks. Integrate Prisma ORM seamlessly into your systems with our expert guidance on data infrastructure and setups. Enjoy the assurance of priority handling of your queries and issues. Influence the future development of the Prisma ORM with your feedback. Protect your critical enterprise data with state-of-the-art security measures. Receive expert advice on optimizing to ensure your software scales effectively and performs optimally, even under the heaviest of loads. As your enterprise grows, our support scales with you. Develop your team's expertise with our in-depth training programs. ## Customized support for enhanced software solutions Engage with the brains behind the Prisma ORM for in-depth problem-solving and specialized insights. Benefit from quick and effective support responses that are crucial in maintaining the pace of your project timelines. Receive personalized advice on tailoring the Prisma ORM to the specific requirements of your unique projects. Stay ahead in the game with the latest updates and best practices. Benefit from prioritized attention to your inquiries and problems. Empower your team with advanced training sessions, enabling them to leverage the full capabilities of our ORM. Ensure your software solutions run smoothly and efficiently. Help you to anticipate and mitigate risks, ensuring a seamless development process and uninterrupted service to your clients. ## Enterprises ## Comprehensive support solutions for your enterprise operations Obtain the level of dedicated support from a team that understands and caters to the complexities and demands of large-scale enterprise operations. Ensuring that your use of the Prisma ORM complies with relevant standards, reducing legal and operational risks. Integrate Prisma ORM seamlessly into your systems with our expert guidance on data infrastructure and setups. Enjoy the assurance of priority handling of your queries and issues. Influence the future development of the Prisma ORM with your feedback. Protect your critical enterprise data with state-of-the-art security measures. Receive expert advice on optimizing to ensure your software scales effectively and performs optimally, even under the heaviest of loads. As your enterprise grows, our support scales with you. Develop your team's expertise with our in-depth training programs. ## Solution Providers ## Customized support for enhanced software solutions Engage with the brains behind the Prisma ORM for in-depth problem-solving and specialized insights. Benefit from quick and effective support responses that are crucial in maintaining the pace of your project timelines. Receive personalized advice on tailoring the Prisma ORM to the specific requirements of your unique projects. Stay ahead in the game with the latest updates and best practices. Benefit from prioritized attention to your inquiries and problems. Empower your team with advanced training sessions, enabling them to leverage the full capabilities of our ORM. Ensure your software solutions run smoothly and efficiently. Help you to anticipate and mitigate risks, ensuring a seamless development process and uninterrupted service to your clients. ## Connect with us Explore how our premium solutions packages can revolutionize your team's approach to developing with Prisma ORM. --- ## [Prisma - Event Code of Conduct](/event-code-of-conduct) **Meta Description:** Read our Event Code of Conduct and how it relates to you. **Content:** ## Event Code of Conduct All attendees, speakers, sponsors, and volunteers at our events and conferences are required to agree to the following code of conduct. Organizers will enforce this code throughout the event. We expect cooperation from all participants to help ensure a safe environment for everybody. Prisma is dedicated to providing a harassment-free experience for everyone, regardless of gender, gender identity and expression, age, sexual orientation, disability, physical appearance, body size, race, ethnicity, religion (or lack thereof), or technology choices. We do not tolerate harassment of participants in any form. Sexual language and imagery are not appropriate for any event venue, including talks, workshops, parties, Twitter, Slack, and other online media. Participants violating these rules may be sanctioned, expelled, or blocked from the event without a refund at the discretion of the organizers. --- ## [Prisma Events](/events) **Meta Description:** Upcoming events or meetups, conferences and and explore the content from previous events. **Content:** ## Prisma Events Find out when the next event or Meetup is happening, at which conferences you can see Prisma folks, and explore the content from previous events. ## Upcoming Events There are currently no upcoming events. Please check back soon ## Prisma Meetups ## Berlin Prisma Meetup Join with other local engineers to discuss the latest database and API developments and learn more about Prisma best practices. ## TypeScript Berlin Meetup For anyone interested in JavaScript frameworks and TypeScript in particular. A Meetup to share knowledge, use cases and solve real problems using technology. ## GraphQL Berlin Meetup A regular meetup of people interested in GraphQL and its ecosystem. We have speakers from all around the globe telling us about the latest developments in the GraphQL world. ## Sponsored Events ## React Day ## Jamstack Conf ## Next.js Conf ## International JavaScript Conference ## If you want to partner on an event, send us your sponsorship deck. ## Past Events ## Prisma Day 2022 June 15-16, 2022 Prisma Day was a two-day hybrid event of talks and workshops about modern application development and databases, featuring and led by members of our community. ## Serverless Conference November 18, 2021 Adopting serverless comes with many challenges. During this event, we covered how to implement flexible, scalable, and low-cost solutions from industry leaders. ## Prisma Day 2021 June 29-30, 2021 Prisma Day was a two day event of talks and workshops by members of the Prisma community, on modern application development. ## Prisma Enterprise Event March 25, 2021 An online conference focused on the challenges large companies and enterprises face with the management of application data. ## Prisma Day 2020 June 25-26, 2020 Prisma Day 2020 was a two day, community-focused online conference on modern application development and databases. ## Prisma Day 2019 June 19, 2019 Prisma Day was a one day, single-track conference in Berlin focused on databases and application development. --- ## [Express & Prisma | Next-Generation ORM for SQL DBs](/express) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build Express apps with MySQL, PostgreSQL & SQL Server databases. **Content:** ## Easy, type-safe database accessin Express servers Query data from MySQL, PostgreSQL & SQL Server databases in Express apps with Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and Express fit together Prisma ORM is a next-generation ORM that's used to query your database in an Express server. You can use it as an alternative to writing plain SQL queries, query builders like knex.js or traditional ORMs like TypeORM, MikroORM and Sequelize.Prisma ORM can be used to build REST and GraphQL APIs and integrates smoothly with both microservices and monolothic architectures. You can also supercharge usage of Prisma ORM with our additional tools:• Prisma Accelerate is a global database cache and scalable connection pool that speeds up your database queries.• Prisma Pulse enables you to build reactive, real-time applications in a type-safe manner. ## Prisma and Express code examples Prisma provides a convenient database access layer that integrates perfectly with Express. The code below demonstrates various uses of Prisma when using Express for building an API server. ## REST API Prisma is used inside your route handlers to read and write data in your database. ## REST API Prisma is used inside your route handlers to read and write data in your database. ## Why Prisma and Express? ## Flexible architecture Prisma fits perfectly into your stack, no matter if you're building microservices or monolothic apps. ## Higher productivity Prisma's gives you autocompletion for database queries, great developer experience and full type safety. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Intuitive data modeling Prisma's declarative modeling language is simple and lets you intuitively describe your database schema. ## Easy database migrations Generate predictible and customizable SQL migrations from the declarative Prisma schema. ## Designed for building APIs Prisma Client reduces boilerplates by providing queries for common API features (e.g. pagination, filters, ...). ## Featured Prisma & Express examples A comprehensive tutorial for building REST APIs with Express, Prisma and PostgreSQL A ready-to-run example project for a REST API with a SQLite database A ready-to-run example project for a GraphQL API with a SQLite database ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Fastify & Prisma | Next-Generation ORM for SQL DBs](/fastify) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build Fastify apps with MySQL, PostgreSQL, SQL Server and MongoDB databases. **Content:** ## Easy, type-safe database Accessin Fastify servers Query data from MySQL, PostgreSQL & SQL Server databases in Fastify apps with Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and Fastify fit together Prisma ORM is a next-generation ORM that's used to query your database in a Fastify server. You can use it as an alternative to writing plain SQL queries, query builders like knex.js or traditional ORMs like TypeORM, MikroORM and Sequelize. Prisma ORM can be used to build REST and GraphQL APIs and integrates smoothly with both microservices and monolithic architectures. You can also supercharge usage of Prisma ORM with our additional tools:• Prisma Accelerate is a global database cache and scalable connection pool that speeds up your database queries.• Prisma Pulse enables you to build reactive, real-time applications in a type-safe manner. ## Prisma and Fastify code examples Prisma provides a convenient database access layer that integrates perfectly with Fastify. The code below demonstrates various uses of Prisma when using Fastify for building an API server. ## REST API Prisma is used inside your route handlers to read and write data in your database. ## REST API Prisma is used inside your route handlers to read and write data in your database. ## Why Prisma and Fastify? ## Flexible architecture Prisma fits perfectly into your stack, no matter if you're building microservices or monolithic apps. ## Higher productivity Prisma's gives you autocompletion for database queries, great developer experience and full type safety. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Intuitive data modeling Prisma's declarative modeling language is simple and lets you intuitively describe your database schema. ## Easy database migrations Generate predictible and customizable SQL migrations from the declarative Prisma schema. ## Designed for building APIs Prisma Client reduces boilerplates by providing queries for common API features (e.g. pagination, filters, ...). ## Featured Prisma & Fastify examples Exploring some of the practices to ensure the reliable operation of a GraphQL server in addition to helping with production troubleshooting. A ready-to-run example project for a REST API with a SQLite database A ready-to-run example project for a GraphQL API with a PosgreSQL database ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Prisma Global Traffic | Prisma](/global) **Meta Description:** Real time activity of the Prisma global data network. **Content:** ## Live Activity Track real-time global traffic as developers build and scale with our commercial products. We pull our live usage data every 60 seconds to keep this map fresh. Curious? Take a look at the Network tab. --- ## [GraphQL with Database & Prisma | Next-Generation ORM for SQL Databases](/graphql) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build GraphQL servers with MySQL, PostgreSQL & SQL Server databases. **Content:** ## Simple Database Accessin GraphQL servers Query data from MySQL, PostgreSQL & SQL Server databases in GraphQL with Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and GraphQL fit together GraphQL provides a powerful way for web and mobile apps to fetch data from an API. However, as a backend developer, you are still responsible for how your GraphQL server retrieves the requested data from the database by implementing your GraphQL resolvers — that's where Prisma ORM comes in. Prisma ORM is used inside of GraphQL resolvers to query a database. It integrates seamlessly with all your favorite tools and libraries from the GraphQL ecosystem. You can also supercharge usage of Prisma ORM with our additional tools:• Prisma Accelerate is a global database cache and scalable connection pool that speeds up your database queries.• Prisma Pulse enables you to build reactive, real-time applications in a type-safe manner. Pulse is the perfect companion to implement GraphQL subscriptions or live queries. ## Prisma Schema The Prisma schema uses Prisma's modeling language to define your database schema. It makes data modeling easy and intuitive, especially when it comes to modeling relations. The syntax of the Prisma schema is heavily inspired by GraphQL SDL. If you're already familiar with SDL, picking it up to model your database tables will be a breeze. ## Prisma and GraphQL use cases Prisma can be used in your GraphQL resolvers, no matter whether you're using an SDL-first approach using makeExecutableSchema from graphql-tools or a code-first approach like Nexus or TypeGraphQL. Note: All examples below are using express-graphql as a GraphQL server, but they also work with any other library like Apollo Server, NestJS or Mercurius. ## GraphQL Tools — SDL-First When using the SDL-first approach for constructing your GraphQL schema, you provide your GraphQL schema definition as a string and a resolver map that implement this definition. Inside your resolvers, you can use Prisma Client to read and write data in your database in order to resolve the incoming GraphQL queries and mutations. ## GraphQL Tools — SDL-First When using the SDL-first approach for constructing your GraphQL schema, you provide your GraphQL schema definition as a string and a resolver map that implement this definition. Inside your resolvers, you can use Prisma Client to read and write data in your database in order to resolve the incoming GraphQL queries and mutations. ## Why Prisma and GraphQL? ## End-to-end type safety Get coherent typings for your application, from database to frontend, to boost productivity and avoid errors. ## Optimized database queries Prisma's built-in dataloader ensures optimized and performant database queries, even for N+1 queries. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Intuitive data modeling Prisma's modeling language is inspired by GraphQL SDL and lets you intuitively describe your database schema. ## Easy database migrations Map your Prisma schema to the database so you don't need to write SQL to manage your database schema. ## Filters, pagination & ordering Prisma Client reduces boilerplates by providing convenient APIs for common database features. ## We ❤️ GraphQL At Prisma, we love GraphQL and believe in its bright future. Since running Graphcool, a popular GraphQL BaaS, we have have been contributing a lot to the GraphQL ecosystem in the past and still invest into a variety of tools that help developers adopt GraphQL. We are also proud members of the GraphQL Foundation where we're helping to push the GraphQL community and ecosystem forward. ## Our GraphQL Resources A weekly newsletter all around the GraphQL community & ecosystem The GraphQL Berlin Meetup has been started in 2016 and is one of the most popular GraphQL Meetups in the world We've built the popular fullstack GraphQL tutorial website How to GraphQL to help educate developers about GraphQL. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Hapi Database & Prisma | Next-Generation ORM for SQL DBs](/hapi) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build hapi apps with MySQL, PostgreSQL & SQL Server databases. **Content:** ## The perfect ORM for hapi developers Query data from MySQL, PostgreSQL & SQL Server databases in hapi apps with Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and hapi fit together Prisma is a next-generation ORM that's used to query your database in a hapi app. You can use it as an alternative to writing plain SQL queries, to using query builders like knex.js or to traditional ORMs like TypeORM, MikroORM and Sequelize. While Prisma works great with hapi, you can use it with any other web framework like koa.js, Fastify or FeathersJS as well. Prisma can be used to build REST and GraphQL APIs and integrates smoothly with both microservices and monolothic architectures. ## Prisma and Hapi use cases Prisma provides a convenient database access layer that integrates perfectly with hapi. The code below demonstrates various uses of Prisma when using hapi for building an API server. ## prismaPlugin A prismaPlugin is the foundation for the domain- or model-specific plugins. The PrismaClient instance it contains provides the database interface to the rest of the application. ## prismaPlugin A prismaPlugin is the foundation for the domain- or model-specific plugins. The PrismaClient instance it contains provides the database interface to the rest of the application. ## Why Prisma and hapi? ## Smooth integration Prisma fits perfectly well into the flexible architecture of hapi, no matter if you're building REST or GraphQL APIs. ## Higher productivity Prisma's gives you autocompletion for database queries, great developer experience and full type safety. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Intuitive data modeling Prisma's declarative modeling language is simple and lets you intuitively describe your database schema. ## Easy database migrations Generate predictible and customizable SQL migrations from the declarative Prisma schema. ## Designed for building APIs Prisma Client reduces boilerplates by providing queries for common API features (e.g. pagination, filters, ...). ## Featured Prisma & hapi Examples A tutorial series for building a modern backend with hapi and Prisma A ready-to-run example project for a REST API with a SQLite database A ready-to-run example project for a GraphQL API with a SQLite database ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Learn how to build applications with Prisma | Prisma](/learn) **Meta Description:** Explore tutorials, examples and other resources to learn how to build web applications using Prisma and various technologies like Next.js, Remix, GraphQL or NestJS. **Content:** ## Learn Prisma Explore our tutorials to learn how to build web applications using Prisma and various technologies like Next.js, Remix, GraphQL, NestJS & more. ## Build a fullstack app with Remix, Prisma & MongoDB ## Build a REST API with NestJS and Prisma ## End-to-end type safety with GraphQL, Prisma and React ## Monitor Your Server with Tracing Using OpenTelemetry & Prisma ## Build a fullstack app with Next.js, GraphQL and Prisma ## Build a GraphQL CRUD API for your Database with TypeGraphQL & Prisma ## Tutorials written by our community Teaching is the best way to learn — check out the tutorials created by amazing community members who went from learners to teachers (or submit your own tutorial for this page). ## Continue learning ## What's new in Prisma Stay up to date with the latest releases with our live streams to discuss all the new features and fixes available in Prisma. Learn the fundamentals and explore all the different concepts of Prisma. Our Data Guide explains the fundamental concepts of databases and related workflows. Explore how to use Prisma with our ready-to-run Prisma example projects. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. ## Meet the team Our Developer Advocates are always happy to help. Feel free to message them on Discord, or Twitter with any questions or feedback you might have. --- ## [Prisma Migrate | Hassle-free Database Migrations](/migrate) **Meta Description:** Automatically generate fully customizable database schema migrations for PostgreSQL, MySQL, MariaDB or SQLite. **Content:** ## Hassle-freeDatabase Migrations Prisma Migrate uses Prisma schema changes to automatically generate fully customizable database schema migrations ## Auto-generated ## Deterministic/Repeatable ## Customizable ## Fast in Development ## Prototype fast without migrations While prototyping you can create the database schema quickly using the prisma db push command without creating migrations. ## Integrated Seeding Quickly seed your database with data by defining a seed script in JavaScript, TypeScript or Shell. ## Smart problem resolution Migrate detects database schema drift and assists you in resolving them. ## Reliable in Production ## Dedicated production workflows Migrate supports dedicated workflows for carrying out migrations safely in production. ## CI/CD Integration Migrate can be integrated into CI/CD pipelines, e.g. GitHub Actions, to automate applying migrations before deployment. ## Conflict detection and resolution Migrate keeps track of applied migrations and provides tools to detect and resolve conflicts and drifts between migrations and the database schema. ## Seamless integration with Prisma Client ## Declarative data modelling ## Version control for your database ## Streamlined collaboration ## Bring your own project --- ## [Prisma & MongoDB | ORM for the scaleable serverless database](/mongodb) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build applications with MongoDB. **Content:** ## Be More Productive withMongoDB & Prisma Bring your developer experience to the next level. Prisma makes it easier than ever to work with your MongoDB database and enables you to query data with confidence. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and MongoDB fit together MongoDB is a powerful NoSQL database that allows developers to intuitively work with their data. However, due to its schemaless nature, developers may run into data inconsistencies as they’re evolving their applications. Prisma is a next-generation ORM/ODM that makes it easier to ensure data consistency by providing an easy-to-read schema and a type-safe database client with auto-completion for all queries. ## Reading data in MongoDB with Prisma Client Prisma Client provides a powerful API for reading data in MongoDB, including filters, pagination, ordering and relational queries for embedded documents and reference-based relations. ## Reading data in MongoDB with Prisma Client Prisma Client provides a powerful API for reading data in MongoDB, including filters, pagination, ordering and relational queries for embedded documents and reference-based relations. “We believe that the combination of MongoDB Atlas Serverless and Prisma Accelerate will greatly simplify the process of building and deploying serverless applications in the cloud, especially for workloads that need to scale to high connection counts.” ## Why Prisma and MongoDB? ## Intuitive Data Modeling The Prisma schema uses an intuitive modeling language that is easy to read and understand for every team member. ## High Productivity & Confidence Prisma has an intuitive querying API with auto-completion so that you can find the right queries directly in your editor. ## Ensured Data Consistency Prisma’s schema-aware database client ensures that you never bring your data in an inconsistent state. ## Fantastic DX Prisma is well-known for its outstanding developer experience and is loved by developers around the world for it. ## First-Class Type-Safety Prisma provides strong type-safety when used with TypeScript, even for relations and partial queries. ## Huge Community & Support Prisma has a huge Discord community, regularly hosts events and provides helpful support via GitHub. ## Build A Fullstack App with Remix, Prisma & MongoDB Through this five-part tutorial, you will learn how to build a fullstack application from the ground up using Prisma with MongoDB.The series covers database configuration, data modeling, authentication, CRUD operations, images uploads and deployment to Vercel. ## Prisma adds support for MongoDB Support for MongoDB has been one of the most requested features since the initial release of the Prisma ORM. Using both technologies together makes developers more productive and allows them to ship more ambitious software faster. Our 3.12 release adds stable and production-ready support for MongoDB. ## Our MongoDB Resources In this guide, you will learn about the concepts behind using Prisma and MongoDB, the commonalities and differences between MongoDB and other database providers, and the process for configuring your application to integrate with MongoDB using Prisma. Learn how to use MongoDB to its fullest to take advantage of the performance and features that developers have grown to rely on. In this episode of What’s New in Prisma, Matt takes you through a demo of the embedded document support in MongoDB. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [NestJS Database & Prisma | Type-safe ORM for SQL Databases](/nestjs) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build NestJS apps with MySQL, PostgreSQL & SQL Server databases. **Content:** ## Next-generation & fully type-safe ORM for NestJS Query data from MySQL, PostgreSQL & SQL Server databases in NestJS apps using Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and NestJS fit together Prisma ORM is a next-generation ORM that can be used to query a database in NestJS apps. It embraces TypeScript to avoid runtime errors and improve productivity. The type-safety it provides goes far beyond the guarantees of traditional ORMs like TypeORM or Sequelize (learn more).Prisma integrates smoothly with the modular architecture of NestJS, no matter if you're building REST or GraphQL APIs. You can also supercharge usage of Prisma ORM with our additional tools:• Prisma Accelerate is a global database cache and scalable connection pool that speeds up your database queries.• Prisma Pulse enables you to build reactive, real-time applications in a type-safe manner. ## Prisma and NestJS code examples Combining NestJS and Prisma provides a new level of type-safety that is impossible to achieve with any other ORM from the Node.js & TypeScript ecosystem. This example demonstrates how to use Prisma Client following NestJS' modular architecture via Dependency Injection by implementing a UserService class that will provide CRUD or domain-specific operations to your application controllers. ## PrismaService A PrismaService class can be implemented by extending the generated PrismaClient in order to build an abstraction of Prisma Client that integrates with your NestJS architecture. It will be provided to other services and controllers via Dependency Injection. ## PrismaService A PrismaService class can be implemented by extending the generated PrismaClient in order to build an abstraction of Prisma Client that integrates with your NestJS architecture. It will be provided to other services and controllers via Dependency Injection. ## Why Prisma and NestJS? ## Embracing TypeScript Prisma is the first ORM that provides full type-safety, even when querying partial models and relations. ## Smooth integration Prisma fits perfectly into the modular architecture of NestJS and provides a powerful database access layer. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Intuitive data modeling Prisma's declarative modeling language is simple and lets you intuitively describe your database schema. ## Easy database migrations Generate predictible and customizable SQL migrations from the declarative Prisma schema. ## Designed for building APIs Prisma Client reduces boilerplates by providing queries for common API features (e.g. pagination, filters, ...). ## Featured Prisma & NestJS community examples A starter kit covering everything you need to build NestJS with Prisma in production. Learn how to use Prisma with NestJS in the official NestJS documentation. A comprehensive workshop and series about building a NestJS REST API with Prisma. An in-depth article about the migration process of a NestJS app from TypeORM to Prisma. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Sign up for Prisma's monthly newsletter](/newsletter) **Meta Description:** The Prisma newsletter is packed with all the latest releases, updates, blogs, and more. Sign up today to stay up-to-date with Prisma. **Content:** ## Get our monthly newsletter ## Sign up for the Prisma newsletter today Get releases updates, tutorials, and more content delivered to your inbox monthly. ## You have successfully subscribed Thank you for joining the Prisma newsletter.You'll be hearing from us soon. ## Latest from the Blog ## Announcing Prisma's MCP Server: Vibe Code with Prisma Postgres Wed Apr 09 2025 With AI-native IDEs, we are all developing apps with remarkable speed. So much so that managing infrastructure is becoming the bottleneck. With Prisma’s MCP server, Cursor, Windsurf and other AI tools, can now provision and manage Postgres databases for your apps, so you don’t have to spend time fiddling with infrastructure. ## Prisma ORM 6.6.0: ESM Support, D1 Migrations & MCP Server Tue Apr 08 2025 The v6.6.0 Prisma ORM release comes packed with exciting features: ESM support via a new generator, Early Access support for Cloudflare D1 and Turso migrations, an MCP server for managing databases directly in your favorite AI tools, and more. ## Rust to TypeScript Update: Boosting Prisma ORM Performance Mon Mar 03 2025 The Query Compiler project upgrades Prisma ORM by swapping out the traditional Rust engine for a leaner solution built on a WASM module and TypeScript. This change boosts query performance and cuts the bundle size by 85–90%, while also improving compatibility with a variety of web frameworks and bundlers. As Prisma ORM heads toward version 7, developers can expect a smoother, more efficient experience. --- ## [Next.js Database with Prisma | Next-Generation ORM for SQL Databases](/nextjs) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build Next.js apps with MySQL, PostgreSQL & SQL Server databases. **Content:** ## The easiest way to workwith a database in Next.js Query data from MySQL, PostgreSQL & SQL Server databases in Next.js apps with Prisma — a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and Next.js fit together Next.js blurs the lines between client and server. It supports pre-rendering pages at build time (SSG) or request time (SSR). Prisma is the perfect companion if you need to work with a database in a Next.js app. You can decide whether to access your database with Prisma at build time (getStaticProps), at request time (getServersideProps), using API routes, or by entirely separating the backend out into a standalone server. If you're in deploying your app to a Serverless or Edge environment, be sure to check out Prisma Accelerate to speed up your database queries. Its scalable connection pool ensures that your database doesn't run out of connections, even during traffic spikes. In addition, it can cache the results of your database queries at the Edge, making for faster response times while reducing the load on your database. ## Static site generation with Prisma The getStaticProps function in Next.js is executed at build time for static site generation (SSG). It's commonly used for static pages, like blogs and marketing sites. You can use Prisma inside of getStaticProps to send queries to your database: Next.js will pass the props to your React components, enabling static rendering of your page with dynamic data. ## Static site generation with Prisma The getStaticProps function in Next.js is executed at build time for static site generation (SSG). It's commonly used for static pages, like blogs and marketing sites. You can use Prisma inside of getStaticProps to send queries to your database: Next.js will pass the props to your React components, enabling static rendering of your page with dynamic data. “Next.js and Prisma is the ultimate combo if you need a database in React apps! Depending on your needs, you can query your database with Prisma in Next.js API routes, in getServerSideProps or in getStaticProps for full rendering flexibility and top performance 🚀” ## Why Prisma and Next.js? ## Full rendering flexibility Display your data using client-side rendering, server-side rendering and static site generation. ## Zero-time database queries Query your database with Prisma in getStaticProps to generate a static page with dynamic data. ## Straightforward deployment Prisma-powered Next.js projects can be deployed on Vercel, a platform built for Next.js apps. ## End-to-end type safety Pairing Prisma with Next.js ensures your app is coherently typed, from the database to your React components. ## Architecture simplicity Less architectural complexity for simple applications – scale the architecture as your application grows. ## Helpful communities Both Next.js and Prisma have vibrant communities where you find support, fun events and awesome people. ## Build a live chat application with the T3 Stack Learn how to build a live chat application with the T3 stack: Next.js, tRPC, Tailwind, TypeScript and Prisma. The video also includes best practices for data modeling as well as features like authentication and realtime updates. It's a comprehensive and practical deep dive into a modern web stack! ## Speed up your app with Prisma Accelerate Prisma Accelerate is a connection pooler and global cache that makes your database queries faster, especially in Serverless and Edge environments. Watch the video to learn how exactly it's used and how you can get started with it in a Next.js app! ## Featured Prisma & Next.js community examples t3 is a web development stack focused on simplicity, modularity, and full-stack type safety. It includes Next.js, tRPC, Tailwind, TypeScript, Prisma and NextAuth. Thanks to its extensive type-safety guarantees, the stack taught by Francisco Mendes in this tutorial is one of the most robust ones to build web applications today. Learn about fullstack development with end-to-end type-safety by creating a fun grocery list application. Blitz.js is an application framework that is built on top of Next.js and Prisma. It brings back the simplicity and conventions of server-rendered frameworks like Ruby on Rails while preserving everything developers love about React and client-side rendering. A starter template for modern web development! CoDox comes with Next.js 13, TypeScript, Tailwind CSS, Shadcn, tRPC, Clerk Auth and a lot more bells and whistels to save you the initial boilerplate for your next Next.js app. This comprehensive 4-hour tutorial teaches you how to build a fullstack form application. The form will be responsive, allow for drag & drop functionality, features different kinds of layout fields like titles, subtitles and paragraphs as well various kinds of field types like text, number, dropdowns, dates, checkbox and textares. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Prisma Optimize: AI-driven query analysis](/optimize) **Meta Description:** Gain deep insights and get actionable recommendations to improve your database queries, making your app run faster. **Content:** ## AI-Driven Query Analysis Gain deep insights and get actionable recommendations to improve your database queries, making your app run faster. ## Insightful and shareable query metrics Gather critical insights into your database queries to enhance application performance. Identify slow queries that introduce additional latency, analyze query groups to identify patterns, and optimize them collectively.
Create shareable query recordings and collaborate with your team to implement recommendations. ## AI powered recommendations Get intelligent recommendations to boost your database performance. Detect missing indexes, uncover unnecessary full table-scans, or identify queries that would benefit from limits.
Optimize helps you rewrite queries or adjust your schema, making you the database expert of your app. ## AI assistant Understand the recommendations easier by asking questions to our Prisma AI. Get help implementing changes, ask follow-up questions, or request a code review. ## Get started for free Use Optimize for free, including a limited number of recommendations per month. Unlock 100 recommendations for $5/month with our Starter plan. Our Pro and Business plans include unlimited recommendations by default. ## What is Optimize ## Faster development, focusing on what matters Enable your team to easily be productive and effective in query optimization, allowing you to concentrate on core development tasks and deliver high-quality applications more quickly. ## Works with the database you already have Designed to work with your current stack, Optimize fits right in without extensive modifications, migrations, or a whole new set of tooling or infrastructure. ## Enhance your application’s performance Integrate Optimize into your project and get your first recommendation in less than 15 minutes. Or experiment with an example app. --- ## [Prisma | Next-generation ORM for Node.js & TypeScript](/orm) **Meta Description:** Prisma is a next-generation Node.js and TypeScript ORM for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB, and CockroachDB. It provides type-safety, automated migrations, and an intuitive data model. **Content:** ## Next-generation Node.js and TypeScript ORM Prisma ORM unlocks a new level of developer experience when working with databases thanks to its intuitive data model, automated migrations, type-safety & auto-completion. ## Delightful DB workflows ## ORM Benchmarks A meaningful comparison of database query latencies across database providers and ORM libraries in the Node.js & TypeScript ecosystem. ## Works with your favorite databases and frameworks Prisma ORM's compatibility with popular tools ensures no stack lock-in, lower integration costs, and smooth transitions. So you have the flexibility to evolve without constraints. ## Data model you can read The Prisma schema is intuitive and lets you declare your database tables in a human-readable way — making your data modeling experience a delight. You define your models by hand or introspect them from an existing database. ## Type-safe database client Prisma Client is a query builder that’s tailored to your schema. We designed its API to be intuitive, both for SQL veterans and developers brand new to databases. The auto-completion helps you figure out your query without the need for documentation. ## Extra ergonomy in VS Code Auto-completion, linting, formatting, and more help developers in VS Code stay confident and productive. ## Make fewer errors with TypeScript Prisma ORM provides the strongest type-safety guarantees of all the ORMs in the TypeScript ecosystem. ## Fully type-safe raw SQL Execute SQL queries directly against your database without losing the benefits of Prisma’s type-checking and auto-completion. TypedSQL leverages the capabilities of Prisma Client to write raw SQL queries that are type-checked at compile time. ## Hassle-free migrations Prisma Migrate auto-generates SQL migrations from your Prisma schema. These migration files are fully customizable, giving you full control and ultimate flexibility — from local development to production environments. ## Visual database browser Prisma Studio is the easiest way to explore and manipulate data in your Prisma projects. Understand your data by browsing across tables, filter, paginate, traverse relations and edit your data with safety. ## Streamline your development workflow ## Development efficiency Prisma ORM simplifies database interactions and provides an intuitive schema migration, enhancing the developer experience. ## Code quality and safety Prisma ORM enhances code reliability and safeguards applications against common vulnerabilities. ## Scalability and portability Prisma ORM supports multiple databases ensuring applications are maintainable - making it easier to adapt and grow. ## Loved by developers ## Real-world apps with Prisma ORM Learn about the amazing open-source projects our community is building. From indie hacking projects to funded startups, you’ll find a lot of fantastic apps. Check them out to learn what and how others are building with Prisma ORM. ## From our community Learn about the amazing open-source projects our community is building. From indie hacking projects to funded startups, you’ll find a lot of fantastic apps. Check them out to learn what and how others are building with Prisma ORM. ## Connect with us ## Streamline your development workflow Start from scratch, add Prisma ORM to your existing project, or explore how to build an app using your favorite framework. --- ## [Prisma | Our OSS Friends](/oss-friends) **Meta Description:** Promoting and supporting the open source community. **Content:** ## Open Source Friends At Prisma, we are proud to promote and support other open source projects and companies. ## Activepieces Activepieces is an open source, no-code, AI-first business automation tool. Alternative to Zapier, Make and Workato. ## Appsmith Build custom software on top of your data. ## Aptabase Analytics for Apps, open source, simple and privacy-friendly. SDKs for Swift, React Native, Electron, Flutter and many others. ## Argos Argos provides the developer tools to debug tests and detect visual regressions. ## BoxyHQ BoxyHQ’s suite of APIs for security and privacy helps engineering teams build and ship compliant cloud applications faster. ## Cal.com Cal.com is a scheduling tool that helps you schedule meetings without the back-and-forth emails. ## ClassroomIO.com ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease. ## Crowd.dev Centralize community, product, and customer data to understand which companies are engaging with your open source project. ## DevHunt Find the best Dev Tools upvoted by the community every week. ## Documenso The Open-Source DocuSign Alternative. We aim to earn your trust by enabling you to self-host the platform and examine its inner workings. ## dyrector.io dyrector.io is an open-source continuous delivery & deployment platform with version management. ## Formbricks Open source survey software and Experience Management Platform. Understand your customers, keep full control over your data. ## Firecamp vscode for apis, open-source postman/insomnia alternative ## Ghostfolio Ghostfolio is a privacy-first, open source dashboard for your personal finances. Designed to simplify asset tracking and empower informed investment decisions. ## GitWonk GitWonk is an open-source technical documentation tool, designed and built focusing on the developer experience. ## Hanko Open-source authentication and user management for the passkey era. Integrated in minutes, for web and mobile apps. ## Hook0 Open-Source Webhooks-as-a-service (WaaS) that makes it easy for developers to send webhooks. ## Inbox Zero Inbox Zero makes it easy to clean up your inbox and reach inbox zero fast. It provides bulk newsletter unsubscribe, cold email blocking, email analytics, and AI automations. ## Infisical Open source, end-to-end encrypted platform that lets you securely manage secrets and configs across your team, devices, and infrastructure. ## KeepHQ Keep is an open-source AIOps (AI for IT operations) platform ## Langfuse Open source LLM engineering platform. Debug, analyze and iterate together. ## Lost Pixel Open source visual regression testing alternative to Percy & Chromatic ## Mockoon Mockoon is the easiest and quickest way to design and run mock REST APIs. ## Novu The open-source notification infrastructure for developers. Simple components and APIs for managing all communication channels in one place. ## OpenBB Democratizing investment research through an open source financial ecosystem. The OpenBB Terminal allows everyone to perform investment research, from everywhere. ## OpenStatus Open-source monitoring platform with beautiful status pages ## Papermark Open-Source Docsend Alternative to securely share documents with real-time analytics. ## Portkey AI AI Gateway with integrated Guardrails. Route to 250+ LLMs and 50+ Guardrails with 1-fast API. Supports caching, retries, and edge deployment for low latency. ## Prisma Simplify working with databases. Build, optimize, and grow your app easily with an intuitive data model, type-safety, automated migrations, connection pooling, caching, and real-time db subscriptions. ## Requestly Makes frontend development cycle 10x faster with API Client, Mock Server, Intercept & Modify HTTP Requests and Session Replays. ## Rivet Open-source solution to deploy, scale, and operate your multiplayer game. ## Shelf.nu Open Source Asset and Equipment tracking software that lets you create QR asset labels, manage and overview your assets across locations. ## Sniffnet Sniffnet is a network monitoring tool to help you easily keep track of your Internet traffic. ## Spark.NET The .NET Web Framework for Makers. Build production ready, full-stack web applications fast without sweating the small stuff. ## Tiledesk The innovative open-source framework for developing LLM-enabled chatbots, Tiledesk empowers developers to create advanced, conversational AI agents. ## Tolgee Software localization from A to Z made really easy. ## Trigger.dev Create long-running Jobs directly in your codebase with features like API integrations, webhooks, scheduling and delays. ## Typebot Typebot gives you powerful blocks to create unique chat experiences. Embed them anywhere on your apps and start collecting results like magic. ## Twenty A modern CRM offering the flexibility of open-source, advanced features and sleek design. ## UnInbox Modern email for teams and professionals. Bringing the best of email and messaging into a single, modern, and secure platform. ## Unkey An API authentication and authorization platform for scaling user facing APIs. Create, verify, and manage low latency API keys in seconds. ## Webiny Open-source enterprise-grade serverless CMS. Own your data. Scale effortlessly. Customize everything. ## Webstudio Webstudio is an open source alternative to Webflow --- ## [Prisma Partner Network - Terms of Services](/partners/tos) **Meta Description:** Terms of Services applicable to the Prisma Partner Network. **Content:** ## Terms of ServicePrisma Partner Network Purpose This Prisma Partner Network Agreement (the “Agreement”) sets out the legally binding terms and conditions of the agreement between you (“Partner” or “you” or “your”) and Prisma Data Inc. (“Prisma” or “we” or “us” or “our”) regarding your participation in the Prisma Partner Network program (the “Program”). By checking the box in the registration process, you agree to be bound by the terms and conditions of this Agreement. Failure to comply with any provisions of the Agreement may result in a loss and/or reduction of Fees and/or Commissions, which decisions shall be made by Prisma in Prisma’s sole discretion. Prisma reserves the right to update and change the Agreement by posting updates and changes to the Prisma website, as applicable, and/or by issuing new Agreement terms. If a significant change is made, we will provide reasonable notice by email. You must read, agree with, and accept all of the terms and conditions contained in this Agreement, including Prisma’s Privacy Policy and Prisma’s Acceptable Use Policy, before you may become a partner. For the avoidance of doubt, Prisma’s Privacy Policy and Acceptable Use Policy form part of this Agreement and are incorporated by reference. For the purposes of the Program and this Agreement, all references to “Account” and “Services” in Prisma’s Acceptable Use Policy will be deemed to refer to “Partner Account” and “Services or Partner’s participation in the Program”, respectively. You may also be required to agree to additional Contract Terms. In the event of a conflict or inconsistency between this Agreement and the Contract Terms, the Agreement will govern, to the extent of such conflict or inconsistency. In addition, some types of Program activities may require that you agree to additional terms (“Additional Terms”). Such Contract Terms and Additional Terms are incorporated into this Agreement by reference. In the event of conflict or inconsistency between this Agreement and the Additional Terms, the Additional Terms will govern, to the extent of such conflict or inconsistency. If you have any questions, please don't hesitate to reach out to us at partnerships@prisma.io. --- ## [Prisma | Partner network](/partners) **Meta Description:** Join our partner network designed for affiliates, technology partners, and resellers. **Content:** ## Powerful database infrastructure on demand. Add Prisma Postgres to your product to deliver instant databases for your users, running on Prisma’s unique high-performance bare metal infrastructure, built on unikernels. ## Postgres for AI agents Deliver unlimited and instant databases to your users. Integrate to Prisma Postgres to your AI agent, to deploy databases in an instant for users. ## Embeddable Database UI Natively embed a rich and mature database web UI into your product. Used by 730k developers every month. Read about how Prisma Postgres is purpose-built to enable AI agents to deploy databases. ## Technology ## Affiliate ## Reseller Join forces with Prisma to unlock new levels of efficiency and innovation for our customers. Our program is perfect for software and platform providers keen on co-creating value through synergy. ## Why partner with Prisma? Integrate your technology with Prisma products, creating seamless solutions that serve our shared user base. Gain exposure to Prisma's growing community through featured spots in our ecosystem, blog posts, and co-hosted webinars Receive priority technical support and early access to Prisma's new features and products. ## Our ideal technology partner Innovators at heart, looking to push the boundaries of database technology. Solutions that complement the Prisma ecosystem, offering added value to our mutual customers. A shared dedication to excellence and high-quality user experiences. We greatly value and respect the creators and educators who incorporate Prisma products in their work. Our Affiliate Program rewards, empowers, and supports your work, all the while ensuring your authenticity and credibility. ## Why become a Prisma Affiliate? You do incredible work. Rewarding you is a small gesture on our part for saying thank you and recognizing the value you bring to our community. Exclusive resources, early access to features, and support from our team, all while allowing you to maintain full editorial control on your content. Once approved, we'll provide you with a unique link. Share it as you wish, with no pressure of quotas. Track your referrals and earnings through a dashboard. Join a network of like-minded creators and gain access to exclusive events, content, and the opportunity to collaborate on projects. ## Rewards & earnings breakdown Earn a 20% commission for 24 months on the monthly revenue from all the users you refer. Commission includes both the base plan fee and any additional usage fees the referred user incurs. Questions about commissions? Hit us up at partnerships@prisma.io We'll invite the top 3 affiliates to our annual company offsite. You’ll get to meet the entire team and share your ideas to help us develop better products. For non-paying platform users signups, we’ll send some cool Prisma swag your way! Expand your offerings with our products, backed by comprehensive training and support. Our program is tailored for those in reselling, system integration, and consulting. ## Why partner with Prisma? Elevate your market presence with our cutting-edge products. Benefit from attractive margins and incentives for expanding Prisma's reach. Acess to comprehensive training and dedicated support to sell and deploy Prisma solutions effectively. ## Our ideal Reseller partner A deep understanding of database technologies and a strong presence in relevant markets. Partners selling to enterprises and looking to enrich their offerings with Prisma's solutions. Commitment to outstanding service and customer success, aligning with our Data DX principles. ## Technology Join forces with Prisma to unlock new levels of efficiency and innovation for our customers. Our program is perfect for software and platform providers keen on co-creating value through synergy. ## Why partner with Prisma? Integrate your technology with Prisma products, creating seamless solutions that serve our shared user base. Gain exposure to Prisma's growing community through featured spots in our ecosystem, blog posts, and co-hosted webinars Receive priority technical support and early access to Prisma's new features and products. ## Our ideal technology partner Innovators at heart, looking to push the boundaries of database technology. Solutions that complement the Prisma ecosystem, offering added value to our mutual customers. A shared dedication to excellence and high-quality user experiences. ## Affiliate ## Reseller ## Join the Prisma Partner Network If you're interested in becoming a part of the Prisma Partner Network, we'd love to hear from you. Questions? Send them over to us at partnerships@prisma.io --- ## [Prisma & PlanetScale | ORM for the scaleable serverless database](/planetscale) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to build applications with PlanetScale **Content:** ## Type-safe access andlimitless scale withPrisma & PlanetScale Query data from PlanetScale with Prisma – a next-generation ORM for Node.js and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and PlanetScale fit together PlanetScale is a MySQL-compatible, serverless database powered by Vitess, which is a database clustering system for horizontal scaling of MySQL. PlanetScale brings many of the benefits of serverless to the database world, with limitless scaling, consumption based pricing, zero-downtime schema migrations, and a generous free tier. Prisma is an open-source ORM that integrates seamlessly with PlanetScale and supports the full development cycle. Prisma helps you define your database schema declaratively using the Prisma schema fetch data from PlanetScale with full type safety using Prisma Client. Used together, you get all the established benefits of relational databases in addition to a modern developer experience, type safe querying, zero ops, and infinite scale. ## Prisma Schema The Prisma schema uses Prisma's modeling language to define your database schema. It makes data modeling easy and intuitive, especially when it comes to modeling relations. The syntax of the Prisma schema is heavily inspired by GraphQL SDL. If you're already familiar with SDL, picking it up to model your database tables will be a breeze. “PlanetScale & Prisma is an unrivaled combination, bringing a supreme developer experience and proven scalability.” ## Why Prisma and PlanetScale? ## Non-blocking schema changes PlanetScale provide a schema change workflow that allows you to update and evolve your database schema without locking or causing downtime for production databases. ## Intuitive data modeling Prisma's modeling language is declarative and lets you intuitively describe your database schema. ## Type-safe database client Prisma Client ensures fully type-safe database queries with benefits like autocompletion - even in JavaScript. ## Built for serverless Avoid the pitfalls of managing servers and deploy your Prisma & PlanetScale project to serverless runtimes for zero ops and limitless scalability. ## Easy database migrations Map your Prisma schema to the database so you don't need to write SQL to manage your database schema. ## Filters, pagination & ordering Prisma Client reduces boilerplates by providing convenient APIs for common database features. ## Prisma & PlanetScale best practices In this video, Daniel guides through everything you need to know when using Prisma with PlanetScale. Learn more about referential integrity and how to operate without foreign key constraints, migration workflows with Prisma and PlanetScale using the prisma db push command, and defining indices on relation scalars (the foreign key fields) for optimal performance. ## Database as code with PlanetScale and Prisma In this talk from Next.js Conf, Taylor Barnett from the PlanetScale team delves into the idea of practicing databases as code, how you can use PlanetScale with Prisma to define your models in a declarative nature and use branching to experiment with your database in an isolated development environment in a serverless stack. ## Our Prisma & PlanetScale Resources This document discusses the concepts behind using Prisma and PlanetScale, explains the commonalities and differences between PlanetScale and other database providers, and leads you through the process for configuring your application to integrate with PlanetScale. Today, Vitess is the default database for scale at Slack, Roblox, Square, Etsy, GitHub, and many more. But how did it get here? From its creation at YouTube to the database that powers PlanetScale, a serverless database platform, Taylor and Sugu will dive into Vitess' creation, why MySQL, what makes Vitess so powerful, and the different ways it is a great fit for developers building serverless applications. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Prisma Playground | Learn the Prisma ORM in your browser](/playground) **Meta Description:** The Playground is an interactive learning environment for Prisma. Learn how to send database queries and explore migrations workflows with the Prisma ORM. **Content:** We are working on a new and improved version of the Prisma Playground! Keep an eye on our channels for when it is released! DocsDiscordX(Twitter) We are working on a new and improved version of the Prisma Playground! Keep an eye on our channels for when it is released! Docs Discord X(Twitter) --- ## [Pricing - Bring Your Own Database - Prisma Data Platform](/pricing/bring-your-own-database) **Meta Description:** Get started for free using Prisma's products or choose the right plan that meets your needs **Content:** ## Start for free, pay as you scale. We only charge for what you use. If you have a quiet month, pay less. If your workload spikes, we can handle it. ## Starter Get started for free. Pay as you go ## ProPay via marketplace Growing for business success ## BusinessPay via marketplace For mission-critical apps All quotas and limits are shared across all databases in your account.*An operation is each time you interact with your database. Read more in the FAQ below. ## Enterprise Get in touch for a custom quote for your enterprise needs. ## Compare plans All of the features below are included with Prisma Postgres ## Managed Connection Pool ## Global Cache ## Database optimizations ## Data management ## Platform ## Managed Connection Pool ## Global Cache ## Database optimizations ## Data management ## Platform ## Frequently asked questionsFAQs An operation is counted each time you do a create, read, update or delete with your Prisma Postgres database. This allows you to intuitively relate your database usage to your own product usage and user behaviour. In some situations, Prisma may run multiple database queries under the covers to satisfy your request, but it will still be counted as just one operation. While the answer to this question will vary from project to project, there are a couple of ways to get an idea of what you will need: We include a free threshold of 100,000 database operations per month on all plans, meaning you can use Prisma for free, and only pay if you exceed the threshold. From our experience, 100,000 operations per month is more than enough to get started. We always send usage notifications to let you know when you’re approaching the threshold, so that you’re always in control of your spending. Yes, you can set limits to ensure you never get a surprise bill. We’ll send you alerts when you reach 75% of your set limit, and if you reach 100% we’ll pause access to your database. This ensures you’ll never have an unexpected bill, and you can always be in complete control of your spending. We record usage at the account level because it gives you, the developer, the most flexibility. You can spin up one database or 20 databases without any extra cost — pay only for the operations you make and storage you use across all of them. This makes experimenting, prototyping and testing ideas super easy and seamless, because you don't have to think about how many databases you create. Traditional pricing is where you choose a fixed database size and price, and the amount you pay is generally predictable. But that comes at the expense of flexibility, meaning it’s much harder to scale up and down with your application’s demands. This is usually fine for a small test database, but for production workloads, it can be burdensome: If you have low-traffic periods, and high-traffic periods (most production apps do) then you either under-provision and risk having downtime in busy periods, or you over-provision and pay a lot more for your database. With usage pricing, you only pay for what you need, when you need it. If your app has a quiet period, you’ll pay less. If things get busy, we can seamlessly scale up to handle it for you, giving you the best of both worlds. Prisma Postgres comes with budget controls, so you can always stay in control of your spending, while taking advantage of the flexibility. Prisma’s pricing is designed to provide maximum flexibility to developers, while aiming to be as intuitive as possible. We charge primarily by operation, which is counted each time you invoke the Prisma ORM client to create, read, update or delete a record. Additionally we also charge for storage. All with a very generous free threshold each month. We don’t charge by data transfer (bandwidth) or by compute/memory hours, simply because we felt that these metrics are more difficult to grasp as a developer. We created a pricing model to more closely match how you use your database as a developer, not how the infrastructure works. Because we only charge you for what you actually use, the best way to see a comparison is to run your application on Prisma, and that’s why we offer a free threshold every month. However, as a simple comparison, the average database operation size from current Prisma users is 10kb (measured from over 15b queries). Some providers charge by bandwidth used, meaning 5GB of bandwidth might equate to approximately 500,000 database operations. You can also connect your own database to Prisma's global caching and connection pooling, also known as Prisma Accelerate. Click the "Bring your own database" toggle at the top of this page to see moredetail. Our pricing is expressed per million, however if you just use one operation (past the free threshold), you will only pay for what you actually use. For example, one database operation on the Pro plan ($8/million operations) would cost $0.000008. --- ## [Pricing - Prisma Data Platform](/pricing) **Meta Description:** Get started for free with Prisma Postgres. Choose the right plan for your workspace based on your project requirements. **Content:** ## Start for free, pay as you scale. We only charge for what you use. If you have a quiet month, pay less. If your workload spikes, we can handle it. ## Starter Get started for free. Pay as you go ## ProPay via marketplace Growing for business success ## BusinessPay via marketplace For mission-critical apps All quotas and limits are shared across all databases in your account.*An operation is each time you interact with your database. Read more in the FAQ below. ## Enterprise Get in touch for a custom quote for your enterprise needs. ## Addons Optional features you can choose to enable to take your app to the next level. ## Programmatic cache invalidation Programatically control your cache invalidation via API. Learn more ## Compare plans All of the features below are included with Prisma Postgres ## Managed Connection Pool ## Global Cache ## Database optimizations ## Data management ## Platform ## Managed Connection Pool ## Global Cache ## Database optimizations ## Data management ## Platform ## Frequently asked questionsFAQs An operation is counted each time you do a create, read, update or delete with your Prisma Postgres database. This allows you to intuitively relate your database usage to your own product usage and user behaviour. In some situations, Prisma may run multiple database queries under the covers to satisfy your request, but it will still be counted as just one operation. While the answer to this question will vary from project to project, there are a couple of ways to get an idea of what you will need: We include a free threshold of 100,000 database operations per month on all plans, meaning you can use Prisma for free, and only pay if you exceed the threshold. From our experience, 100,000 operations per month is more than enough to get started. We always send usage notifications to let you know when you’re approaching the threshold, so that you’re always in control of your spending. Yes, you can set limits to ensure you never get a surprise bill. We’ll send you alerts when you reach 75% of your set limit, and if you reach 100% we’ll pause access to your database. This ensures you’ll never have an unexpected bill, and you can always be in complete control of your spending. We record usage at the account level because it gives you, the developer, the most flexibility. You can spin up one database or 20 databases without any extra cost — pay only for the operations you make and storage you use across all of them. This makes experimenting, prototyping and testing ideas super easy and seamless, because you don't have to think about how many databases you create. Traditional pricing is where you choose a fixed database size and price, and the amount you pay is generally predictable. But that comes at the expense of flexibility, meaning it’s much harder to scale up and down with your application’s demands. This is usually fine for a small test database, but for production workloads, it can be burdensome: If you have low-traffic periods, and high-traffic periods (most production apps do) then you either under-provision and risk having downtime in busy periods, or you over-provision and pay a lot more for your database. With usage pricing, you only pay for what you need, when you need it. If your app has a quiet period, you’ll pay less. If things get busy, we can seamlessly scale up to handle it for you, giving you the best of both worlds. Prisma Postgres comes with budget controls, so you can always stay in control of your spending, while taking advantage of the flexibility. Prisma’s pricing is designed to provide maximum flexibility to developers, while aiming to be as intuitive as possible. We charge primarily by operation, which is counted each time you invoke the Prisma ORM client to create, read, update or delete a record. Additionally we also charge for storage. All with a very generous free threshold each month. We don’t charge by data transfer (bandwidth) or by compute/memory hours, simply because we felt that these metrics are more difficult to grasp as a developer. We created a pricing model to more closely match how you use your database as a developer, not how the infrastructure works. Because we only charge you for what you actually use, the best way to see a comparison is to run your application on Prisma, and that’s why we offer a free threshold every month. However, as a simple comparison, the average database operation size from current Prisma users is 10kb (measured from over 15b queries). Some providers charge by bandwidth used, meaning 5GB of bandwidth might equate to approximately 500,000 database operations. You can also connect your own database to Prisma's global caching and connection pooling, also known as Prisma Accelerate. Click the "Bring your own database" toggle at the top of this page to see moredetail. Our pricing is expressed per million, however if you just use one operation (past the free threshold), you will only pay for what you actually use. For example, one database operation on the Pro plan ($8/million operations) would cost $0.000008. --- ## [Privacy Policy | Prisma](/privacy) **Meta Description:** Read our privacy policy and see how it relates to you. **Content:** ## Privacy Policy Whenever possible, we recommend contacting us via the built-in integration on console.prisma.io over direct email support. This provides additional features that are not available otherwise and helps us provide a quicker turnaround and more accurate responses. This Privacy Statement covers the information practices of prisma.io, console.prisma.io, cloud.prisma.io, cloudprojects.prisma.io, optimize.prisma.io and graph.cool. --- ## [React with Prisma | Next-Generation Node.js and TypeScript ORM](/react-server-components) **Meta Description:** Prisma is a next-generation ORM for Node.js & TypeScript. It's the easiest way to connect React apps to MySQL, PostgreSQL, SQL Server, CockroachDB, and MongoDB databases. **Content:** ## Access your Database fromReact Server Components with Ease Query data from MySQL, PostgreSQL, SQL Server, CockroachDB, and MongoDB databases in React Server Components with Prisma – a better ORM for JavaScript and TypeScript. ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and React Server Components fit together React is a popular library for building user interfaces in JavaScript. It is used to build frontend applications that run in web browsers. With React Server Components, React components can now be rendered on the server as well. React Server Components have full access to server-side functionality, like file systems and databases. That's where Prisma ORM comes in: Prisma ORM is the best way for React developers to query a database in React Server Components. You can also supercharge usage of Prisma ORM with our additional tools:• Prisma Accelerate is a global database cache and scalable connection pool that speeds up your database queries.• Prisma Pulse enables you to build reactive, real-time applications in a type-safe manner. Pulse is the perfect companion to implement GraphQL subscriptions or live queries. ## Prisma in React Server Components React Server Components are rendered on the server, meaning they can communicate directly with a database using @prisma/client for safe and efficient database access.Prisma provides a developer-friendly API for constructing database queries. Under the hood, it generates the required query and sends them to the database. ## Prisma in React Server Components React Server Components are rendered on the server, meaning they can communicate directly with a database using @prisma/client for safe and efficient database access.Prisma provides a developer-friendly API for constructing database queries. Under the hood, it generates the required query and sends them to the database. ## Why Prisma and React Server Components? ## No SQL required Prisma makes database queries easy with a slick and intuitive API to read and write data. ## Better performance Querying your database in React Server Components significantly increases performance of your app. ## Intuitive data modeling Prisma's declarative modeling language is simple and lets you intuitively describe your database schema. ## End-to-end type safety Pairing Prisma with React ensures your app is coherently typed, from the database to your frontend. ## Higher productivity Prisma's gives you autocompletion for database queries, great developer experience and full type safety. ## Helpful communities Both React and Prisma have vibrant communities where you find support, fun events and awesome people. ## Featured Prisma & React Community Examples This guide is a thorough introduction to building production-ready fullstack apps using React (via Next.js), Prisma and PostgreSQL. It includes authentication via NextAuth.js and deployment via Vercel. RedwoodJS is a fullstack application framework. Built on React, GraphQL, and Prisma, it works with the components and development workflow you love, but with simple conventions and helpers to make your experience even better. ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [Serverless Deep Dive](/serverless) **Meta Description:** The latest trends, challenges, and solutions in the world of serverless technology shared by practitioners and innovators. **Content:** ## Serverless Deep Dive Together with practitioners and innovators, we dive in and take a look at the latest trends, challenges, and solutions in the world of serverless. ## DATE COMING SOON ## The serverless architecture Serverless computing offers a new way of designing and deploying applications using cloud services. But what exactly is it and how does it work? Serverless computing is a fairly recent evolution in the cloud computing space. Serverless providers allow developers to focus on the functionality that their... The serverless paradigm represents a notable shift in the way that application and web developers interact with infrastructure, language runtimes, and supplemental services. The role of databases within many organizations has evolved over time. While reliance on data to build applications, make business decisions, and provide value in larger ecosystems has increased, the management of the database software and infrastructure itself has, in many cases, shifted. The introduction of serverless capabilities into the developer landscape has transformed the way a lot of people work with their data and build their applications. ## Serverless Deep Dive - June 20th, 2023 With Rob Reid and Mahmoud Abdelwahab, we discuss database solutions in serverless architecture, including use cases and best practices for serverless applications. ## Serverless Deep Dive - May 23rd 2023 With Yan Cui and Taylor Barnett-Torabi we dig deep into Serverless with databases, developer experience, texting and tooling. ## Serverless Deep Dive - May 3rd 2023 With Alex DeBrie and Jeremy Daly, we chat about the challenges and latest solutions in the world of Serverless. --- ## [Prisma Showcase | Customer Success stories](/showcase) **Meta Description:** Learn how companies are leveraging our powerful, next-generation, type-safe ORM for Node.js. **Content:** ## Made with Prisma Learn how companies use Prisma in production Building with Prisma? Show it off with ↗ ## How Prisma helps Amplication evolutionize backend development Amplication is an open-source development tool. It helps you develop quality Node.js applications without spending time on repetitive coding tasks. It’s perfect for both backend and fullstack developers. ## Formbricks and Prisma Accelerate: Solving scalability together Formbricks, an open-source survey platform, effectively tackled scalability challenges with Prisma Accelerate and strategically integrated it to manage growing user demands and maintain high performance. ## How Solin uses Accelerate to serve 2.5M database queries per day Learn how Prisma Accelerate has contributed to Solin's success by enhancing performance and reliability with its scalable connection pool and global database cache. ## How Elsevier piloted an innovative publication process quickly and flexibly with Prisma Elsevier is a global leader in information and analytics in scientific publishing and helps researchers and healthcare professionals. With the help of Prisma, Elsevier is in the process of modernizing the scientific publishing process efficiently and with flexibility. ## How Tryg has leveraged Prisma to democratize data Tryg saved huge amounts of time thanks to its “360” Data Broker platform that accelerated development cycles by removing the overhead incurred by configuring environments manually. Prisma was the critical technology that enabled them to democratize billions of records from different data sources. ## How Panther champions talent over geography with Prisma Panther leverages Prisma and a cutting edge tech stack to power a domain-driven architecture. This allows Panther to ensure that its customers can automate global payroll and compliance for their remote teams with one click. ## How Prisma helps Rapha manage their mobile application data Rapha is a company dedicated to redefining comfort, performance, and style for cyclists around the world, whether beginners or World Tour professionals. Learn how Prisma helps Rapha build consistent data APIs across various teams and platforms. ## How Grover moves faster with Prisma Grover offers monthly tech product subscriptions and splits work on its services across many teams. Some teams have recently found huge productivity gains by adopting Prisma. Read on to find out how Prisma has benefited Grover and how you can benefit as well. ## How migrating from Sequelize to Prisma allowed Invisible to scale Invisible is a B2B productivity startup that allows its users to automate and outsource any complex workflow or business process through Worksharing. Prisma played a crucial role in allowing Invisible to future proof their tech stack and in supporting its scale. ## How Prisma allowed Pearly to scale quickly with an ultra-lean team Pearly provides a platform for dentists to create better and reliable revenue streams and affordable care plans for their patients. Learn how Prisma has helped them scale quickly with an ultra-lean team. ## How Poppy uses Prisma Client to ship confidently Poppy offers rides of all kinds through its mobile app. Whether its a car, scooter, or e-step, Poppy has it. Prisma plays a vital role in helping Poppy ship quickly and confidently and is a big reason they ve just hit 1.5 million total rides taken. ## How iopool refactored their app in less than 6 months with Prisma In 2020, iopool realized that their architecture was slowing them down and preventing them from innovating. They decided to switch to Lambda functions and a PostgreSQL database powered by Prisma. Learn how this has helped them move fast with confidence and has greatly simplified their process. ## Built with Prisma South Pole has been at the forefront of decarbonization since 2006, developing and implementing comprehensive strategies that turn climate action into long-term business opportunities for Fortune 500 companies, governments and organizations around the world. Garages Near Me is an online platform for drivers and parking providers. Born on the web, the platform helps people and businesses list, share, book, and pay for long-term parking spaces across Germany and beyond. Wasp is the fastest way to develop full-stack web apps in React & Node.js. Describe high-level features (auth, CRUD, async jobs, …) via a simple config language, and write the rest of your logic in React, Node.js and Prisma. Sunhat is an automation-focused software company founded to rethink sustainability compliance from the ground up. We are building an all-in-one SaaS platform to help companies automate and scale their sustainability programs. CoinRotator tracks price trends for the top 1,500 cryptocurrencies, all updated daily on a single dashboard. Instantly check the coin screener for each market using their proprietary version of the Supertrend. Gamma is an alternative to slide decks - a fast, simple way to share and present your work. Create engaging presentations, memos, briefs, and docs that are easy to discuss live or share async. All in your browser, nothing to download or install. --- ## [Service Level Agreement (SLA) | Prisma](/sla) **Meta Description:** Explore our Service Level Agreement (SLA) detailing our monthly uptime percentage, service credits, and any exclusions. **Content:** ## Prisma Service Level Agreement Prisma strives to ensure reliable access to our services, aiming to maintain a Monthly Uptime Percentage (as defined below) of no less than 99.95% for all billing cycles each month. This is our assurance of service availability to our users (referred to as the "Service Commitment"). For clarity and understanding, the following terms are defined as such: This is a dollar-denominated credit that may be applied to an eligible Prisma workspace, as calculated and determined in accordance with the conditions outlined below. Should Prisma Services experience a Downtime Period, we offer compensation through Service Credits, calculated as a percentage of the total monthly service fees paid for the affected service. This calculation does not include any one-time or prepaid charges, nor does it account for any fees related to professional services, technical support, or maintenance. Service Credits accrued can only be applied to future payments for Prisma Services. Service Credits are non-refundable and cannot be exchanged for cash or other forms of payment. To be applicable, the Service Credit for a particular billing cycle must exceed one dollar ($1 USD). Service Credits are non-transferable and cannot be applied to any account other than the one experiencing the Downtime Period. The Terms of Service stipulate that the allocation of a Service Credit is your exclusive remedy for any failure on our part to deliver the agreed level of service. The Service Commitment does not cover situations where Prisma Services are unavailable, suspended, or performing sub-optimally due to: We reserve the right, at our discretion, to issue a Service Credit in situations where factors not included in the Monthly Uptime Percentage calculation affect service availability. To submit a claim for a Service Credit, follow these steps in the Prisma Platform Console: Claims must be submitted within two billing cycles following the incident, and must include all required information to qualify for a Service Credit. If your claim is validated and the Monthly Uptime Percentage falls below the Service Commitment, the Service Credit will be issued within one billing cycle following the month of claim validation. Incomplete or inaccurate claims will render you ineligible for a Service Credit. Pulse Exclusions Pulse offers “at least once” semantics and does not currently guarantee event delivery, including but not limited to “at most once” or “exactly once” guarantees. --- ## [Prisma in your stack | Prisma](/stack) **Meta Description:** Prisma is a Node.js and TypeScript ORM that integrates easily with popular databases, and frameworks. **Content:** ## Works with your favorite databases and frameworks ## Languages ## Prisma can be used in any Node.js or TypeScript backend application. ## Databases ## Prisma works seamlessly across most popular databases and service providers. ## Frameworks ## Here is a non-exhaustive list of libraries and frameworks you can use with Prisma. ## If you want to explore Prisma with any these technologies or others, you can checkout our ready-to-run examples. ## Explore drop-in extensible solutions created by members of the Prisma Community. --- ## [Prisma Startup Program](/startups) **Meta Description:** The Prisma Startup Program is designed to help early-stage founders focus on scaling their businesses, and not managing databases. **Content:** ## Fuel your startup'ssuccess with Prisma Get exclusive 1:1 guidance from Prisma’s database experts, and have your database bill covered for a year and up to $10,000. $10k credits – to fuel your database operations. Get 1:1 guidance from Prisma experts
– to help you build smarter and faster Direct support in Slack – so help is just a quick message away. ## Why join Prisma for Startups? Building a startup is hard – your tools shouldn’t be. You need infra that grows with you: flexible, powerful, and built to scale. Prisma helps you stay laser-focused on your mission by removing database complexity and streamlining your workflow. ## Bootstrapped? At least 5k MRR for the last 6 months Two full-time team members Can do attitude 😉 ## Eligibility Pre-seed, seed, or series-A Raised in the last 12 months Founded in the last 5 years Prisma empowers you to innovate faster with the most reliable and developer-friendly database infrastructure. Build with confidence, scale without limits, and deliver exceptional experiences to your global audience—all while staying focused on what matters: your product. ## Startups building with Prisma We adopted Prisma conventions as our standard, and it saves lots of time having from reinventing things ourselves. Thanks to Prisma, we can seamlessly scale our applications without concerns about data layer performance. Entire SaaS businesses have been built on top of the Prisma ecosystem— including OSS ones like Dub.co. Have been loving the recent performance improvements as well ## Apply below --- ## [Prisma Studio | Next-generation ORM for Node.js and TypeScript](/studio) **Meta Description:** The easiest way to explore and manipulate your data in all of your Prisma projects. **Content:** ## Explore and understand your data The ultimate tool for exploring and editing data in your Prisma project. Work locally or team up in Prisma Console to seamlessly collaborate on data management with your team. ## EMBEDDED IN THE PRISMA DATA PLATFORM ## Native to your workflow ## Instant Access to Your Database Connect to your Prisma Postgres database or bring your own in seconds. Prisma Studio now lives right in the Prisma Data Platform. ## Zero Setup Required Skip installation and dive straight into your data. Your entire team can access and collaborate instantly. ## Real-Time Collaboration Work together on the same database in real time. No local setup, no configuration - just seamless teamwork. ## Local or collaborative Access your database anywhere - work locally for rapid development or use Console for team collaboration. Switch seamlessly between solo and team workflows. ## Understand your data Browse your database visually with powerful filters and search. Spot patterns instantly and get insights for debugging or schema changes - no SQL needed. ## Power through complexity Visualize complex data relationships with clickable model navigation. See your database architecture unfold naturally, helping teams understand how everything connects. ## Switch contexts instantly Find exactly what you need with powerful, precise filtering. Combine filters and operators to quickly surface insights from complex data. See your data clearly through the perfect lens. ## See how Studio works Access Prisma Studio on your local machine during development or in the Prisma Console to easily collaborate on data with your team. Bring your own database or use Prisma Postgres for fast and easy access to your data. ## Try it out! Get started locally with a pre-seeded database and example project. --- ## [Support Policy | Prisma](/support-policy) **Meta Description:** Read our support policy and see how it relates to you. **Content:** ## Prisma Support Policy At Prisma, developer experience is at the heart of everything we do. Getting help when you need it is an essential part of that DX, just as great tooling, docs, or a great API are.This page provides you with information about our Support Policy and how you can get help to resolve your inquiries best. To resolve any issues with our products, we highly recommend starting with our comprehensive documentation. Additionally, our "Ask AI" feature, integrated within the documentation, is readily available to assist all users and customers. ## Support Services for Prisma ORM Support for Prisma’s Open-Source Software (OSS), including the Prisma ORM, is provided through our Community channels: GitHub, Discord.Prisma also offers custom support packages for enterprises and solutions providers. ## Support Services for Prisma Data Platform Prisma provides support for Prisma Data Platform customers based on their selected plan. You can find out more about the available plans on our Pricing page. Platform plan Starter Pro Business Enterprise Support plan Community Standard Business Dedicated Discord ✅ ✅ ✅ ✅ Contact via Console - ✅ ✅ ✅ Email via support@prisma.io - ✅ ✅ ✅ Dedicated contact - - - ✅ Starter Support plan Community Discord ✅ Contact via Console - Email via support@prisma.io - Dedicated contact - Pro Support plan Standard Discord ✅ Contact via Console ✅ Email via support@prisma.io ✅ Dedicated contact - Business Support plan Business Discord ✅ Contact via Console ✅ Email via support@prisma.io ✅ Dedicated contact - Enterprise Support plan Dedicated Discord ✅ Contact via Console ✅ Email via support@prisma.io ✅ Dedicated contact ✅ Whenever possible, we recommend contacting us via the built-in integration on console.prisma.io over direct email support. This provides additional features that are not available otherwise and helps us provide a quicker turnaround and more accurate responses. We aim to respond to all requests in a timely manner. Support requests are prioritized based on the requester’s plan and the severity of their issue. Platform plan Support plan Response time Starter Community No guaranteed response time. We strive to reply to all requests within 3 business days. Pro Standard 2 business days Business Business 1 business hour Enterprise Dedicated Custom Support plan Starter Community Pro Standard Business Business Enterprise Dedicated Response time Starter No guaranteed response time. We strive to reply to all requests within 3 business days. Pro 2 business days Business 1 business hour Enterprise Custom Our business hours are 9am-5pm CET on regular weekdays, Monday to Friday, except for public holidays in Germany (see below). We provide additional coverage under our dedicated support plans for customers on our Enterprise plan. ## Additional Information The severity level will be indicated by the Customer when submitting a Support Request. We may set, upgrade, and downgrade the severity level of Support Requests at our discretion based on the information available. Level Definition P1 - Urgent priority Critical Issue Defect resulting in full or partial system outage or a condition that makes the affected Prisma product unusable or unavailable in production for all of the Customer’s Users. P2 - High priority Significant Disruption Issue resulting in impacted major functionality or significant performance degradation, impacting a significant portion of the user base. P3 - Normal priority Minor Feature or Functional Issue / General Question Issue resulting in a Prisma component not performing as expected or documented, or an inquiry regarding a general technical issue or general question. P4 - Low priority Minor issue / Feature Request An information request about Prisma or a feature request. Definition P1 - Urgent priority Critical Issue Defect resulting in full or partial system outage or a condition that makes the affected Prisma product unusable or unavailable in production for all of the Customer’s Users. P2 - High priority Significant Disruption Issue resulting in impacted major functionality or significant performance degradation, impacting a significant portion of the user base. P3 - Normal priority Minor Feature or Functional Issue / General Question Issue resulting in a Prisma component not performing as expected or documented, or an inquiry regarding a general technical issue or general question. P4 - Low priority Minor issue / Feature Request An information request about Prisma or a feature request. --- ## [Prisma Support](/support) **Meta Description:** Explore comprehensive support articles, resources, and guides for Prisma ORM, Accelerate, and Pulse. Find the best solution and get help from our team. **Content:** ## How can we help? ## Issues & Feature Requests for the ORM Found a bug, or want to request something new? Let us know. ## On the Starter plan? Support for customers on our Starter plan is provided through our community channels. ## On the Pro or Business plan? Support for customers on our Pro or Business plan is provided through the Platform Console. ## Still need help? We're here to help. Response times depend on your subscription level and the volume of requests we're receiving. ## Interested in solutions for your enterprise operations? --- ## [Terms of Service](/terms) **Meta Description:** Read our terms of services and see how they relate to you. **Content:** ## Terms of Service 1.1 Your use of the Prisma service is governed by this agreement (the "Terms"). "Prisma" means Prisma Data, Inc and its subsidiaries or affiliates involved in providing the Prisma Service. The "Prisma Services" means the services Prisma makes available through this website, including this website, the Prisma cloud computing platform, the Prisma API, the Prisma Add-ons, and any other software or services offered by Prisma in connection to any of those. This also includes any products that Prisma makes available as Early Access releases of its upcoming offerings. 1.2 In order to use the Prisma Services, you must first agree to the Terms. You can agree to the Terms by actually using the Prisma Services. You understand and agree that Prisma will treat your use of the Prisma Services as acceptance of the Terms from that point onwards. 1.3 You may not use the Prisma Services if you are a person barred from receiving the Prisma Services under the laws of the United States or other countries, including the country in which you are resident or from which you use the Prisma Services. You affirm that you are over the age of 13, as the Prisma Services may not be used by children under 13. 1.4 You agree your purchases of Prisma Services are not contingent on the delivery of any future functionality or features or dependent on any oral or written public comments made by Prisma or any of its affiliates regarding future functionality or features. 1.5 "Early Access" refers to a phase of product development where the product or service is made available to the public before its official, finalized release. During the Early Access phase, the product may not include all planned features and may undergo significant changes as development progresses. The purpose of this phase is to gather user feedback and identify potential issues or improvements, influencing the final version of the product. It is important to note that an Early Access product is provided 'as is', and may have bugs, errors, or other issues that may or may not be addressed before the final release. Features may be added, removed, or significantly altered during the course of development and testing. Additionally, at the end of an Early Access period, Prisma holds the right to wipe any data collected or retained during the Early Access period. 1.6 Usage of Prisma Optimize in Production: Prisma Optimize is intended for testing and development purposes only. It should not be used in production environments, as it may result in unforeseen issues, including data loss. Users assume all risks when using it beyond its recommended scope. --- ## [TypedSQL: Fully type-safe raw SQL in Prisma ORM](/typedsql) **Meta Description:** Write raw sql queries with fully type-safety and auto-completion in Prisma ORM. Get type-safe database queries without sacrificing the power and flexibility of raw SQL. **Content:** ## Fully type-safe raw SQL TypedSQL is the best way to express the full power of SQL in queries. Fully type-safe, with auto-completion, and a fantastic DX for using raw SQL with Prisma. ## End-to-end type-safety All TypedSQL queries have typed inputs and outputs preventing errors related to incorrect types and improving DX. Any type mismatches can be caught right away, while type-safety significantly improves ergonomics while developing. ## Full control of SQL When you need the full control of the SQL engine, write and execute raw SQL queries directly. This gives you the flexibility to use advanced SQL-specific features and optimizations that are not available in the Prisma Client API, while maintaining type safety. ## Great DX TypedSQL combines the productivity of a higher-level abstraction with type-safety for crafting SQL directly.Use familiar SQL tools in your editor, complete with syntax highlighting, error checking, and autocompletion. Benefit from intelligent suggestions, and seamlessly switch between the Prisma Client API and SQL. ## See TypedSQL in action ## Expand your capabilities Built on Prisma Client, TypedSQL pairs well with all Prisma products and features. ## Works alongside Prisma Schema & Migrate TypedSQL complements Prisma Schema and Prisma Migrate. It extends the functionality you’re already used to with type-safe SQL queries. ## Use with Prisma Accelerate & Optimize Continue using SQL queries while benefiting from products built for Prisma Client, such as connection pooling provided by Accelerate and insightful query metrics and recommendations with Optimize. ## Raw SQL with type-safety and autocompletion TypedSQL gives you even more flexibility and control in your database queries. Start using TypedSQL in any new or existing Prisma project. --- ## [TypeScript & Prisma | TypeScript ORM for SQL Databases](/typescript) **Meta Description:** Prisma is a TypeScript ORM that makes you more confident with type safe database access. It's the easiest way to access SQL databases in Node.js with TypeScript **Content:** ## TypeScript ORMwith zero-cost type-safety for your database Query data from MySQL, PostgreSQL & SQL Server databases with Prisma – a type-safe TypeScript ORM for Node.js ## What is Prisma? Prisma makes working with data easy! It offers a type-safe Node.js & TypeScript ORM, global database caching, connection pooling, and real-time database events. ## How Prisma and TypeScript fit together TypeScript is a statically typed language which builds on JavaScript. It provides you with all the functionality of JavaScript with the additional ability to type and verify your code which saves you time by catching errors and providing fixes before you run your code. All valid JavaScript code is also TypeScript code which makes TypeScript easy for you to adopt. Prisma is an ORM for Node.js and TypeScript that gives you the benefits of type-safety at zero cost by auto-generating types from your database schema. It's ideal for building reliable data intensive application. Prisma makes you more confident and productive when storing data in a relational database. You can use it with any Node.js server framework to interact with your database. ## Prisma Schema The Prisma schema uses Prisma's modeling language to define your database schema and to generate the corresponding TypeScript types. It makes data modeling easy and intuitive, especially when it comes to modeling relations. The types generated from the Prisma schema ensure that all your database queries are type safe. Prisma Client gives you a fantastic autocomplete experience so you can move quickly and be sure you don't write an invalid query. ## Prisma and TypeScript code examples Define your schema once and Prisma will generate the TypeScript types for you. No need for manual syncing between the types in your database schema and application code. The code below demonstrates how database queries with Prisma are fully type safe – for all queries, including partial queries, and relations. ## Zero-cost type-safety Queries with Prisma Client always have their return type inferred making it easy to reason about the returned data – even when you fetch relations. ## Zero-cost type-safety Queries with Prisma Client always have their return type inferred making it easy to reason about the returned data – even when you fetch relations. ## Why Prisma and TypeScript? ## Type-safe database client Prisma Client ensures fully type-safe database queries so that you never write an invalid query ## Optimized database queries Prisma's built-in dataloader ensures optimized and performant database queries, even for N+1 queries. ## Autocompletion Prisma helps you write your queries with rich autocompletion as you write queries ## Type inference Queries with Prisma Client always have their return type inferred making it easy to reason about your data. ## Easy database migrations Map your Prisma schema to the database so you don't need to write SQL to manage your database schema. ## Filters, pagination & ordering Prisma Client reduces boilerplates by providing convenient APIs for common database features. ## We ❤️ TypeScript At Prisma, we love TypeScript and believe in its bright future. Since the inception of Prisma, we've pushed the TypeScript compiler to its limits in order to provide unprecedented type-safe database access, and rich autocompletion for a delightful developer experience. Prisma is built with type-safety at its heart so that you make less mistakes. By tapping into TypeScript's structural type system Prisma maps database queries into structural types so you can know the precise shape of the data returned for every Prisma Client query you write. ## Our TypeScript Resources The TypeScript Berlin Meetup started in 2019 and is one of the most popular TypeScript Meetups in the world Ready-to-run example projects using Prisma, TypeScript and a variety of different frameworks and API technologies A tutorial series for building a modern backend with hapi and Prisma ## Join the Prisma Community We have multiple channels where you can engage with members of our community as well as the Prisma team. ## Discord Chat in real-time, hang out, and share ideas with community members and our team. ## GitHub Browse the Prisma source code, send feedback, and get answers to your technical questions. ## Twitter Stay updated, engage with our team, and become an integral part of our vibrant online community. --- ## [A Business Case for Extended ESOP Exercise Windows](/blog/esop-exercise-windows) **Meta Description:** Explore extending ESOPs to 10 years, considering fairness, economics, benefits, challenges with Prisma's example, and startup compensation. **Content:** Employee Stock Options Programs (ESOPs) are commonplace in the startup ecosystem, with nearly every startup in the USA and Europe, including Prisma, implementing some form of ESOP. They evoke a wide range of opinions and emotions, and their consequences have become a source of folklore and myths. Some perceive ESOPs as a means to extraordinary wealth, while others regard them as mere lottery tickets or tools to persuade employees to accept lower salaries. These differing views are a reflection of the reality shaped by the design of ESOPs. This blog post aims to discuss the concept of 90-day exercise windows in programs and explain why we decided to extend this period to 10 years at Prisma. We believe that this change is not only fair to our team, but also a good business decision. ## The problem with 90-day exercise windows Exercise windows are the amount of time a team member has to exercise their stock options after leaving a company before they are forfeited and returned to the stock option pool, and [according to Carta](https://carta.com/blog/pte-90-day-window/), in Q4 2022 ~83% of companies follow a 90-day exercise window. Startup employees have widely criticized 90-day exercise windows. One critique comes from Zach Holman in his colorful [blog post](https://zachholman.com/posts/fuck-your-90-day-exercise-window/) published back in 2016. As Holman points out, 90-day exercise windows impose a financial burden on employees leaving the company, requiring them to use their own money to exercise their stock options in exchange for shares in a notoriously risky investment. This is even worse in some European countries, such as Germany, where Capital Gains Tax is applied to unrealized gains. Suddenly, employees not only have to find the money to exercise their options, but they also need to pay the accompanying tax bill. Added together, the exercise of stock options and the accompanying taxes could be tens to hundreds of thousands of dollars in some instances. It's easy to understand why many employees have been skeptical about the value of ESOPs, and some have accused these plans of being disproportionately favorable to team members from rich families, possibly perpetuating wealth inequality. To address this situation, some companies — including Prisma — have opted to extend the exercise windows for their teams. This extension ranges from 10 years to shorter time periods. You can find a list of some of these companies [here](https://github.com/holman/extended-exercise-windows) on GitHub. ## Why we chose a 10-year exercise window Prisma was established in 2016, then known as Graphcool. Similar to many other companies, we followed the standard 90-day exercise period. In 2021, with unanimous support from our Board of Directors, we extended our ESOP exercise window to 10 years, and in line with our value of Transparency, we also published this on our [careers page](https://www.prisma.io/careers). This decision stemmed from our commitment to our team, recognizing the critical contributions of current and former team members in our success, and a belief that everyone who contributed to Prisma should have an opportunity to benefit from its success. Our 10-year exercise window reinforces this belief by providing past team members with: - additional time to improve their personal financial situation before needing to exercise their stock options; - time for more information to be gained about Prisma’s prospective success and thereby - reducing the overall risk of the investment. Finally, this change benefited many of our team members based in Berlin, Germany, where we previously had our largest office. Unfavorable German tax laws affected a significant number of our team, and this adjustment helped them avoid extraordinarily high tax payments if they were to exercise their options upon departure. Although extended exercise periods are popular with employees, there are ample critics who have valid concerns about this approach, as illustrated by [this post](https://a16z.com/the-lack-of-options-for-startup-employees-options/) from Andreessen Horowitz. ## Criticism of extended exercise windows From a *fairness* perspective, critics have pointed out that the longer exercise period will perpetuate a *wealth transfer*. Former team members, who are no longer contributing to the company can hold on to their options for an extended period, benefiting from the work of current team members. From an *economics* perspective, it is argued that the prolonged exercise window may lead to an increased rate of dilution for current employees. > *Dilution is the decrease in ownership percentage for existing shareholders when a company issues or reserves new shares of stock. —* ([Carta](https://carta.com/blog/how-to-manage-equity-dilution-as-an-early-stage-startup/)) > It is argued that dilution would be amplified because of former employees retaining their options, forcing the company to refresh the option pool more frequently to attract new talent or incentivize existing team-members. This dilution can impact the ownership percentage of current team members in the company. These concerns are not entirely wrong, and could be mitigated by a change in perspective, and some adjusted financial modelling. Below are a few perspectives we hod at Prisma seeks a compromise between the interests of current team-members, former team-members, founders, investors, and other shareholders. ### About fairness: Standing on the shoulders of giants The concern raised by critics about *"wealth transfer"* overlooks a fundamental issue. Many new and current team members can only join a company because of the success achieved by those who came before them. It also seems unfair that a team-member who joined when the startup was just starting out should have to take a much bigger financial risk to make money from their stock options compared to an employee who joined later. One way to address this is by offering larger stock option grants to early-stage employees, typically coupled with a lower exercise price. This is intended to serve as compensation for the risk involved. However, some people argue that employees in the early stages should accept lower salaries in exchange for these bigger stock option grants. This means that early-stage employees have to accept both lower salaries and more investment risk. It is not clear whether the larger stock option grants and exercise price they receive are enough to make up for these sacrifices. Resolving fairness problems is always difficult. Having longer exercise periods can both help and hinder fairness, depending on the situation. Any company that chooses to have longer exercise periods should consider implementing measures to revoke this benefit when it is undeserved by departing team-members. What is evident is that the argument against longer exercise periods based on the "wealth transfer" is not fully convincing. ### About economics: Mitigating dilution through increased present value The second concern — the economics of extended exercise windows and its effect on dilution — is also not complete. By considering the *Present Value* (PV) of stock options, a different approach can be pursued. Specifically, extending the exercise window for stock options increases the chances for team members to benefit from their options. This is because the probability of a liquidity event (IPO, purchase, secondary sale, etc.) increases with time. Due to the time value of money, the PV of stock options with a longer (e.g. 10-year) exercise window would therefore be more than the PV of stock options with a shorter (e.g. 90-day) exercise window - all things being equal. Due to the higher PV, startups could justifiably reduce the size of stock option grants in relation to market standards. This helps reduce the dilution effect on the options pool caused by the extended exercise period. It also addresses investor concerns and maintains hiring competitiveness by retaining more options in the pool. By reducing the size of stock option grants and increasing the exercise windows, more employees will be able to benefit from their stock options, although the size of the individual grants would be smaller. This more equitable distribution would eliminate the stark contrast between employees who can exercise their stock options and those who cannot. This would ultimately increase the perceived value of Employee Stock Ownership Plans (ESOPs) as more individuals benefit from them. Additionally, this could enhance the overall perceived value of compensation packages without incurring any cost to companies. Following this, there is a strong business case to increase exercise windows to benefit from the economics. The question is really not *if* this should be done, but rather *how* this should be done. 10 Year exercise windows are not always the best option. It will depend on the *Startup* to *IPO* timeframe a company expects, among other factors. In addition, arriving at a Present Value would require the company to make some impossible assumptions about the *Future Value* (FV), and the *Rate of Return* (r). Ultimately, the idea is not to try and engage in detailed financial modeling but rather to implement an approach that approximates future expectations and changes over time as more information becomes available. ## Unintended consequences Prisma’s decision to move to a 10-year exercise window was well-received internally, and it aligned clearly with our values and addressed some (although not all) concerns of our more "options-skeptic" European colleagues. However, it is not a panacea for all problems related to equity compensation. To ensure the health of our Stock Option, we needed to reduce the size of all stock option grants. An unintended consequence of this is that savvy employment candidates would compare the size of Prisma's grants to market data and correctly notice that the overall percentage of company ownership was less than what they might receive at similar companies. Fortunately, these same candidates were predominantly receptive toward the benefits accrued by the extended exercise window, and no offers were rejected on this basis. On the contrary, most candidates reacted positively to the approach when explained to them. As Prisma approaches its 8-year anniversary in 2024, there are new challenges on the horizon. We are slowly approaching the 10-year post-grant limit for early employees, after which unexercised stock options are absorbed back into the company. This means that past employees will need to decide whether or not to exercise their stock options. If they choose not to, unexercised options will return to the options pool and render the fairness arguments made by Andreessen Horowitz irrelevant in the Prisma context. This situation will require us to reevaluate as we collect data on stock option exercise rates and their impact on the options pool. Another concern arising from the extended exercise period is the large number of grant holders that need to be interacted with over a long period of time. There seems to be no meaningful way to mitigate this. Overall, the 10-year extended exercise period has worked well in Prisma’s context, both in terms of fairness and economics. Partially because of our history, partially because we have strong European roots, and partially because of our culture. It is not for everyone, although we hope that our experience will start conversations for other companies to consider this approach. --- ## [Prisma 2.10 Adds Preview Support for Microsoft SQL Server](/blog/prisma-sql-server-support-preview-a4anl2gd8d3a) **Meta Description:** No description available. **Content:** ## Contents - [TL;DR](#tldr) - [Expanding supported databases in Prisma](#expanding-supported-databases-in-prisma) - [Getting started](#getting-started) - [Limitations](#limitations) - [Try Prisma with SQL Server and share your feedback](#try-prisma-with-sql-server-and-share-your-feedback) ## TL;DR - Prisma release [2.10.0](https://github.com/prisma/prisma/releases/tag/2.10.0) adds preview support for Microsoft SQL Server. - You can use Prisma Client with SQL Server through introspection. - Check out the [**Start from scratch guide**](https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-sqlserver) in the docs. ## Expanding supported databases in Prisma Today we are excited to introduce an initial preview of support for SQL Server! 🎉 Earlier this year we released Prisma Client for general availability with support for PostgreSQL, MySQL, SQLite, and MariaDB. Since then, we've heard from thousands of engineers about how Prisma Client is helping them build apps faster by making database access easy. This release marks the first milestone since [SQL Server was originally requested](https://github.com/prisma/prisma/issues/2430) by a community member. We are now a step closer to providing the same streamlined developer experience, type safety, and productivity to developers using SQL Server SQL Server support has passed rigorous testing internally, and is now ready for testing by the community, **however, as a preview feature, it is not production-ready.** To read more about what preview means, check out the [maturity levels](https://www.prisma.io/docs/about/prisma/releases#preview) in the Prisma docs. Thus, we're inviting the SQL Server community to try it out and [give us feedback](https://github.com/prisma/prisma/issues/4039) so we can bring SQL Server support to general availability. 🚀 Your feedback and suggestion will help us shape the future of SQL Server support in Prisma. 🙌 ## Getting started This release allows you to try out Prisma Client with an existing SQL Server database. With Prima's introspection workflow, you begin by introspecting (`prisma introspect`) an existing SQL Server database which populates the Prisma schema with models mirroring the state of your database schema. Then you can generate Prisma Client (`prisma generate`) and interact with your database in a type-safe manner with Node.js or TypeScript. As Prisma Migrate does not yet support SQL Server, if you're starting without an existing database, you will need to define the schema with SQL or using a visual modeling tool, e.g., [DBeaver](https://dbeaver.io/) or [SQL Server Management Studio](https://docs.microsoft.com/en-us/sql/ssms/sql-server-management-studio-ssms). **You can use this [guide](https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-sqlserver) to get started with Prisma and an SQL Server database.** You can also dig into our ready-to-run [example](https://github.com/prisma/prisma-examples/tree/latest/databases/sql-server) in the [`prisma-examples`](https://github.com/prisma/prisma-examples) repo which includes the SQL to create a database and instructions on how to introspect and use Prisma Client with SQL Server. ## Limitations Support for SQL Server comes with some limitations that are detailed in this section. **Prisma Migrate is not supported yet** Prisma Migrate does not support SQL Server yet. This means that you can continue using whichever migration tool to alter the database schema and then use introspection to keep the Prisma schema in sync with the database schema. To follow progress on this issue, subscribe to [issue #4074 on GitHub](https://github.com/prisma/prisma/issues/4074). **TLS encryption should be disabled when connecting from macOS** TLS encryption needs to be disabled when connecting to an SQL Server database from macOS due to trusted certificate requirements imposed by macOS 10.15. This means that you can't connect to an Azure SQL database directly from a Mac with this release. To disable encryption, add the `encrypt=DANGER_PLAINTEXT` parameter to the connection string. > **Note that disabling TLS should only be done during development as it's a security risk otherwise.** To follow progress on this issue, subscribe to [issue #4075 on GitHub](https://github.com/prisma/prisma/issues/4075) **TCP required on the service** Your SQL server must support TCP communication. We do not provide any support for the in-memory protocol or named pipes. Things might change in the future, but if using the Windows installation of SQL Server, TCP communication needs to be enabled for Prisma to work. ## Try Prisma with SQL Server and share your feedback We built this for you and are eager to hear your feedback! ☎️ [Schedule a call](https://calendly.com/labas-prisma/sqlserver-feedback) with our Product team to tell us everything about your project, and get an exclusive T-Shirt. 🐜 Tried it out and found that it's missing something or stumbled upon a bug? Please [file an issue](https://github.com/prisma/prisma/issues/new/choose) so we can look into it. 🌍 We also invite you to join our [Slack](https://slack.prisma.io/) where you can discuss all things Prisma, share feedback in the `#product-feedback` channel, and get help from the community. 🏗 We are excited to finally share the preview version of SQL Server support in Prisma and can't wait to see what you all build with it.
--- ## [How TypeScript 4.9 `satisfies` Your Prisma Workflows](/blog/satisfies-operator-ur8ys8ccq7zb) **Meta Description:** Learn how TypeScript 4.9''s new `satisfies` operator can help you write type-safe code with Prisma **Content:** ## Table Of Contents - [A little background](#a-little-background) - [Constrained identity functions](#constrained-identity-functions) - [Introducing `satisfies`](#introducing-satisfies) - [Infer Prisma output types without `Prisma.validator`](#infer-prisma-output-types-without-prismavalidator) - [Infer the output type of methods like `findMany` and `create`](#infer-the-output-type-of-methods-like-findmany-and-create) - [Infer the output type of the `count` method](#infer-the-output-type-of-the-count-method) - [Infer the output type of the `aggregate` method](#infer-the-output-type-of-the-aggregate-method) - [Infer the output type of the `groupBy` method](#infer-the-output-type-of-the-groupby-method) - [Create lossless schema validators](#create-lossless-schema-validators) - [Define a collection of reusable query filters](#define-a-collection-of-reusable-query-filters) - [Strongly typed functions with inferred return types](#strongly-typed-functions-with-inferred-return-types) - [Wrapping up](#wrapping-up) ## A little background One of TypeScript's strengths is how it can _infer_ the type of an expression from context. For example, you can declare a variable without a type annotation, and its type will be inferred from the value you assign to it. This is especially useful when the exact type of a value is complex, and explicitly annotating the type would require a lot of duplicate code. Sometimes, though, explicit type annotations are useful. They can help convey the _intent_ of your code to other developers, and they keep TypeScript errors as close to the actual source of the error as possible. Consider some code that defines subscription pricing tiers and turns them into strings using the [`toFixed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) method on `Number`: ```typescript const plans = { personal: 10, team: (users: number) => users * 5, enterprie: (users: number) => users * 20, // ^^ Oh no! We have a typo in "enterprise" }; // We can use `Number` methods on `plans.personal` const pricingA = plans.personal.toFixed(2); // We can call `plans.team` as a function const pricingB = plans.team(10).toFixed(2); // ERROR: Property 'enterprise' does not exist on type... const pricingC = plans.enterprise(50).toFixed(2); ``` If we use an explicit type annotation on `plans`, we can catch the typo earlier, as well as infer the type of the `users` arguments. However, we might run into a different problem: ```typescript type Plan = "personal" | "team" | "enterprise"; type Pricing = number | ((users: number) => number); const plans: Record = { personal: 10, team: (users) => users * 5, // We now catch this error immediately at the source: // ERROR: 'enterprie' does not exist in type... enterprie: (users) => users * 20, }; // ERROR: Property 'toFixed' does not exist on type 'Pricing'. const pricingA = plans.personal.toFixed(2); // ERROR: This expression is not callable. const pricingB = plans.team(10).toFixed(2); ``` When we use an explicit type annotation, the type gets "widened", and TypeScript can no longer tell which of our plans have flat pricing and which have per-user pricing. Effectively, we have "lost" some information about our application's types. What we really need is a way to assert that a value is compatible with some broad / reusable type, while letting TypeScript infer a narrower (more specific) type. ### Constrained identity functions Before TypeScript 4.9, a solution to this problem was to use a ["constrained identity function"](https://kentcdodds.com/blog/how-to-write-a-constrained-identity-function-in-typescript). This is a generic, no-op function that takes an argument and a type parameter, ensuring the two are compatible. An example of this kind of function is the [`Prisma.validator`](https://www.prisma.io/docs/orm/prisma-client/type-safety/prisma-validator) utility, which also does some extra work to only allow known fields defined in the provided generic type. Unfortunately, this solution incurs some runtime overhead just to make TypeScript happy at compile time. There must be a better way! ### Introducing `satisfies` The new `satisfies` operator gives the same benefits, with no runtime impact, and automatically checks for excess or misspelled properties. Let's look at what our pricing tiers example might look like in TypeScript 4.9: ```typescript type Plan = "personal" | "team" | "enterprise"; type Pricing = number | ((users: number) => number); const plans = { personal: 10, team: (users) => users * 5, // ERROR: 'enterprie' does not exist in type... enterprie: (users) => users * 20, } satisfies Record; // No error! const pricingA = plans.personal.toFixed(2); // No error! const pricingB = plans.team(10).toFixed(2); ``` Now we catch the typo right at the source, but we don't "lose" any information to type widening. The rest of this article will cover some real situations where you might use `satisfies` in your Prisma application. ## Infer Prisma output types without `Prisma.validator` Prisma Client uses generic functions to give you type-safe results. The static types of data returned from client methods match the shape you asked for in a query. This works great when calling a Prisma method directly with inline arguments: ```typescript import { Prisma } from "@prisma/client"; // Fetch specific fields and relations from the database: const post = await prisma.post.findUnique({ where: { id: 3 }, select: { title: true, createdAt: true, author: { name: true, email: true, }, }, }); // TypeScript knows which fields are available: console.log(post.author.name); ``` ```prisma model Post { id String @id @default(cuid()) title String body String createdAt DateTime @default(now()) author Author @relation(fields: [authorId], references: [id]) authorId String } model Author { id String @id @default(cuid()) name String email String posts Post[] } ``` However, you might run into some pitfalls: - If you try to break your query arguments out into smaller objects, type information can get "lost" (widened) and Prisma might not infer the output types correctly. - It can be difficult to get a type that represents the output of a specific query. The `satisfies` operator can help. ### Infer the output type of methods like `findMany` and `create` One of the most common use cases for the `satisfies` operator with Prisma is to infer the return type of a specific query method like a `findUnique` — including only the selected fields of a model and its relations. ```typescript import { Prisma } from "@prisma/client"; // Create a strongly typed `PostSelect` object with `satisfies` const postSelect = { title: true, createdAt: true, author: { name: true, email: true, }, } satisfies Prisma.PostSelect; // Infer the resulting payload type type MyPostPayload = Prisma.PostGetPayload<{ select: typeof postSelect }>; // The result type is equivalent to `MyPostPayload | null` const post = await prisma.post.findUnique({ where: { id: 3 }, select: postSelect, }); ``` ```prisma model Post { id String @id @default(cuid()) title String body String createdAt DateTime @default(now()) author Author @relation(fields: [authorId], references: [id]) authorId String } model Author { id String @id @default(cuid()) name String email String posts Post[] } ``` ### Infer the output type of the `count` method Prisma Client's `count` method allows you to add a `select` field, in order to count rows with non-null values for specified fields. The return type of this method depends on which fields you specified: ```typescript import { Prisma } from "@prisma/client"; // Create a strongly typed `UserCountAggregateInputType` to count all users and users with a non-null name const countSelect = { _all: true, name: true, } satisfies Prisma.UserCountAggregateInputType; // Infer the resulting payload type type MyCountPayload = Prisma.GetScalarType< typeof countSelect, Prisma.UserCountAggregateOutputType >; // The result type is equivalent to `MyCountPayload` const count = await prisma.user.count({ select: countSelect, }); ``` ```prisma model User { id String @id @default(cuid()) name String country String profileViews Int } ``` ### Infer the output type of the `aggregate` method We can also get the output shape of the more flexible `aggregate` method, which lets us get the average, min value, max value, and counts of various model fields: ```typescript import { Prisma } from "@prisma/client"; // Create a strongly typed `UserAggregateArgs` to get the average number of profile views for all users const aggregateArgs = { _avg: { profileViews: true, }, } satisfies Prisma.UserAggregateArgs; // Infer the resulting payload type type MyAggregatePayload = Prisma.GetUserAggregateType; // The result type is equivalent to `MyAggregatePayload` const aggregate = await prisma.user.aggregate(aggregateArgs); ``` ```prisma model User { id String @id @default(cuid()) name String country String profileViews Int } ``` ### Infer the output type of the `groupBy` method The `groupBy` method allows you to perform aggregations on groups of model instances. The results will include fields that are used for grouping, as well as the results of aggregating fields. Here's how you can use `satisfies` to infer the output type: ```typescript import { Prisma } from "@prisma/client"; // Create a strongly typed `UserGroupByArgs` to get the sum of profile views for users grouped by country const groupByArgs = { by: ["country"], _sum: { profileViews: true, }, } satisfies Prisma.UserGroupByArgs; // Infer the resulting payload type type MyGroupByPayload = Awaited< Prisma.GetUserGroupByPayload >; // The result type is equivalent to `MyGroupByPayload` const groups = await prisma.user.groupBy(groupByArgs); ``` ```prisma model User { id String @id @default(cuid()) name String country String profileViews Int } ``` ## Create lossless schema validators Schema validation libraries (such as a [zod](https://github.com/CarterGrimmeisen/zod-prisma) or [superstruct](https://github.com/ianstormtaylor/superstruct)) are a good option for sanitizing user input at runtime. Some of these libraries can help you reduce duplicate type definitions by inferring a schema's static type. Sometimes, though, you might want to create a schema validator for an existing TypeScript type (like an input type generated by Prisma). For example, given a `Post` type like this in your Prisma schema file: ```prisma model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) } ``` Prisma will generate the following `PostCreateInput` type: ```typescript export type PostCreateInput = { title: string; content?: string | null; published?: boolean; }; ``` If you try to create a schema with [zod](https://github.com/colinhacks/zod) that matches this type, you will "lose" some information about the schema object: ```typescript const schema: z.ZodType = z.object({ title: z.string(), content: z.string().nullish(), published: z.boolean().optional(), }); // We should be able to call methods like `pick` and `omit` on `z.object()` schemas, but we get an error: // TS Error: Property 'pick' does not exist on type 'ZodType'. const titleOnly = schema.pick({ title: true }); ``` A workaround before TypeScript 4.9 was to create a [`schemaForType` function](https://github.com/colinhacks/zod/discussions/667) (a kind of constrained identity function). Now with the `satisfies` operator, you can create a schema for an existing type, without losing any information about the schema. Here are some examples for four popular schema validation libraries: ```typescript import { Prisma } from "@prisma/client"; import { z } from "zod"; const schema = z.object({ title: z.string(), content: z.string().nullish(), published: z.boolean().optional(), }) satisfies z.ZodType; type Inferred = z.infer; ``` ```typescript import { Prisma } from "@prisma/client"; import { boolean, Describe, Infer, nullable, object, optional, string } from "superstruct"; const schema = object({ title: string(), content: optional(nullable(string())), published: optional(boolean()), }) satisfies Describe; type Inferred = Infer; ``` ```typescript import { Prisma } from "@prisma/client"; import { boolean, InferType, object, ObjectSchema, string } from "yup"; const schema = object({ title: string().required(), content: string().nullable(), published: boolean(), }) satisfies ObjectSchema; type Inferred = InferType; ``` ```typescript import { Prisma } from "@prisma/client"; import { pipe } from "fp-ts/lib/function"; import * as D from "io-ts/Decoder"; const schema = pipe( D.struct({ title: D.string, }), D.intersect( D.partial({ content: D.nullable(D.string), published: D.boolean, }) ) ) satisfies D.Decoder; type Inferred = D.TypeOf; ``` ### Define a collection of reusable query filters As your application grows, you might use the same filtering logic across many queries. You may want to define some common filters which can be reused and composed into more complex queries. Some ORMs have built-in ways to do this — for example, you can define [model scopes](https://guides.rubyonrails.org/active_record_querying.html#scopes) in Ruby on Rails, or create [custom queryset methods](https://docs.djangoproject.com/en/4.1/topics/db/managers/#calling-custom-queryset-methods-from-the-manager) in Django. With Prisma, `where` conditions are object literals and can be composed with `AND`, `OR`, and `NOT`. The `satisfies` operator gives us a convenient way to define a collection of reusable filters: ```typescript const { isPublic, byAuthor, hasRecentComments } = { isPublic: () => ({ published: true, deletedAt: null, }), byAuthor: (authorId: string) => ({ authorId, }), hasRecentComments: (date: Date) => ({ comments: { some: { createdAt: { gte: date }, }, }, }), } satisfies Record Prisma.PostWhereInput>; const posts = await prisma.post.findMany({ where: { AND: [isPublic(), byAuthor(userID), hasRecentComments(yesterday)], }, }); ``` ### Strongly typed functions with inferred return types Sometimes you might want to assert that a function matches a special function signature, such as a React component or a Remix loader function. In cases like Remix loaders, you also want TypeScript to infer the specific shape returned by the function. Before TypeScript 4.9, it was difficult to achieve both of these at once. With the `satisfies` operator, we can now ensure a function matches a special function signature without widening its return type. Let's take a look at an example with a Remix loader that returns some data from Prisma: ```typescript import { json, LoaderFunction } from "@remix-run/node"; import invariant from "tiny-invariant"; import { prisma } from "~/db.server"; export const loader = (async ({ params }) => { invariant(params.slug, "Expected params.slug"); const post = await prisma.post.findUnique({ where: { slug: params.slug }, include: { comments: true }, }); if (post === null) { throw json("Not Found", { status: 404 }); } return json({ post }); }) satisfies LoaderFunction; export default function PostPage() { const { post } = useLoaderData(); return (

{post.title}

{post.body}
    {post.comments.map((comment) => (
  • {comment.body}
  • ))}
); } ``` Here the `satisfies` operator does three things: - Ensures our `loader` function is compatible with the `LoaderFunction` signature from Remix - Infers the argument types for our function from the `LoaderFunction` signature so we don't have to annotate them manually - Infers that our function returns a `Post` object from Prisma, including its related `comments` ## Wrapping up TypeScript and Prisma make it easy to get type-safe database access in your application. Prisma's API is designed to provide [zero-cost type safety](https://dev.to/prisma/productive-development-with-prisma-s-zero-cost-type-safety-4od2), so that in most cases you automatically get strong type checking without having to "opt in", clutter your code with type annotations, or provide generic arguments. We're excited to see how new TypeScript features like the `satisfies` operator can help you get better type safety, even in more advanced cases, with minimal type noise. Let us know how you are using Prisma and TypeScript 4.9 by reaching out to us on our [Twitter](https://twitter.com/prisma). --- ## [Bringing Prisma ORM to React Native and Expo](/blog/bringing-prisma-orm-to-react-native-and-expo) **Meta Description:** Prisma ORM now provides Early Access support for React Native and Expo. The integration introduces reactive queries, using React hooks to auto-update the UI when the underlying data changes. **Content:** Prisma ORM is the preferred way to work with databases in backend JavaScript applications. This is due to its excellent type-safety, easy migration system and tight integration into your favorite IDE. We got the first request to support React Native back in 2019, and since then [the issue has gotten more than 300 upvotes](https://github.com/prisma/prisma/issues/5011). We always wanted Prisma to power the data of local apps - both on mobile, web and desktop, so this community interest made sense to us. But we also knew that porting Prisma ORM to mobile wouldn’t cut it. Apps are different than web servers, and to provide excellent DX, we would need to build additional functionality to offer tight integration with the underlying platform. So that’s what we have been doing, and today, we are excited to announce the [Early Access of Prisma ORM for React Native and Expo](https://github.com/prisma/react-native-prisma) 🎉  We have worked with [Expo](https://expo.dev/) to make sure it’s easy to use in an app managed by Expo, and the readme contains documentation to set up Prisma ORM in a React Native app not managed by Expo. ## Reactive Queries In addition to the full Prisma ORM API, we are introducing a new set of query functions that integrate with React’s hook mechanism to automatically update your UI when the underlying data changes. We call these Reactive Queries, and it works like this: ```prisma export default function TransactionList() { const transactions = prisma.transactions.useFindMany({ orderBy: { date: "desc" }}) return ( {transactions.map((transaction) => { return ( prisma.transactions.delete({ where: { id: transaction.id } })} > ); })} ); } ``` In this component, we declare the data dependency at the top. Instead of using Prisma ORM’s normal `findMany()` query function, we use the new `useFindMany()` query function which integrates directly with the React `useState()` and `useEffect()` mechanisms to re-render the component when the underlying data changes. This line initially returns an empty array and then re-renders the component as soon as the list of transactions is fetched from the local database: ```ts prisma.transactions.useFindMany({ orderBy: { date: "desc" }}) ``` > It is customary for hooks in React to be free standing functions - for example `useFindManyTransactions()`. To conform with the regular Prisma ORM API, we have chosen the alternative format `prisma.transactions.useFindMany()`. During this Early Access period, we are soliciting feedback on this decision. Please share your thoughts on [Discord](https://discord.com/channels/937751382725886062/1242744051070009354). In the `LongPress` handler, the database row is deleted, automatically triggering a re-render of the component. It’s important to note that data changes can happen anywhere in your application, and it will trigger a re-render of any active component that relies on that data. ```ts () => prisma.transactions.delete({ where: { id: transaction.id } }) ``` By taking advantage of Reactive Queries, many applications can be refactored to remove brittle and manual state management in favor of a simple automated reactivity model. ## Prisma ORM in your Expo App today Prisma ORM is ready to be used in your Expo and React Native app today. Keep in mind this is an Early Access release, so please help us test it out and share your experience with us [on Discord](https://discord.com/channels/937751382725886062/1242744051070009354). To get started, follow the [instructions in the readme](https://github.com/prisma/react-native-prisma). ### A Local-First experiment We have designed the reactive query system to work directly with a fully integrated sync service in the future. This will enable you to write applications that work with local data for the best user experience while syncing automatically in the background to enable powerful experiences such as live collaboration, presence indication, and data sharing. We aren’t ready to talk about this just yet, but you can take a look at an experimental implementation of this concept in the [GitHub repo](https://github.com/sorenbs/budget-buddy-experimental-sync). --- ## [Prisma ORM Support for Edge Functions is Now in Preview](/blog/prisma-orm-support-for-edge-functions-is-now-in-preview) **Meta Description:** We're thrilled to share that you can now access your database with Prisma ORM from Vercel Edge Functions and Cloudflare Workers. **Content:** ## What are edge functions? Edge functions are a form of lightweight serverless compute that's distributed across the globe. They allow you to deploy and run your apps as closely as possible to your end users. ![](https://cdn.sanity.io/images/p2zxqf70/production/cdc1687a8bc84dd978cd3e2270618719a6da7207-1920x1080.png) ### Edge functions can make your app faster Thanks to the geographically distributed nature of edge functions, the distance between the user and the data center is reduced. This decreases request latency and improves response times, making edge functions a great approach to increase performance and notably improve the user experience of an app. ### Technical constraints in edge functions Vercel Edge Functions and Cloudflare Workers don't use the standard Node.js runtime. Instead, they are running code in [V8 isolates](https://www.cloudflare.com/learning/serverless/glossary/what-is-chrome-v8/). As a consequence, these edge functions only have access to a small subset of the standard Node.js APIs and also have constrained computing resources (CPU and memory). In particular, the constraint of not being able to freely open TCP connections makes it difficult to talk to a traditional database from an edge function. While Cloudflare has introduced a [`connect()`](https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/) API that enables limited TCP connections, this still only enables database access using specific database drivers that are compatible with that API. > **Note:** In the Node.js ecosystem, the most popular traditional database driver [compatible with Cloudflare Workers](https://developers.cloudflare.com/workers/tutorials/postgres/) is [`node-postgres`](https://node-postgres.com/) for PostgreSQL. However, there is also [work being done](https://github.com/sidorares/node-mysql2/pull/2289) to make MySQL compatible with Cloudflare Workers in the `node-mysql2` driver. Modern database providers, such as [Neon](https://neon.tech/docs/serverless/serverless-driver) or [PlanetScale](https://planetscale.com/docs/tutorials/planetscale-serverless-driver), have worked around this limitation by releasing [_serverless drivers_](https://www.prisma.io/blog/serverless-database-drivers-KML1ehXORxZV#what-are-serverless-database-drivers) that talk to the database via HTTP. ## Database access in edge functions with Prisma ORM 🎉 While it was possible to use Prisma ORM in an edge function in earlier versions, this always required usage of [Prisma Accelerate](https://www.prisma.io/data-platform/accelerate) as a proxy between the edge function and the database. ![](https://cdn.sanity.io/images/p2zxqf70/production/4b2cd3e2d1da28a2f29ced7d34f75ac7bbd08f94-2532x1210.png) It was not possible to "just" deploy an app with Prisma ORM to the edge due to the technical constraints mentioned above: - Database access only works with specific drivers (either a serverless driver or a driver that's compatible with Cloudflare's `connect()`). The problem here was that Prisma ORM only used to have _built-in_ drivers in its query engine and thus couldn't use the compatible Node.js drivers. - Size limitations of the application bundle that's uploaded to an edge function made it impossible to use Prisma ORM because its query engine was too large and exceeded the size limit. - Edge functions only allows access to a limited set of Node.js APIs. Some of these APIs are required for Prisma Client to work though, so not having access to these requires Prisma Client to work around some of the limitations. ![](https://cdn.sanity.io/images/p2zxqf70/production/b67a096af36af4026cd5c6b36b34a7693d0f2ce1-2532x1210.png) We are excited that the [`v5.11.0`](https://github.com/prisma/prisma/releases/tag/5.11.0) release lifts these restrictions and enables running Prisma ORM in edge functions in Preview 🎉 ![](https://cdn.sanity.io/images/p2zxqf70/production/4a84546e5ae706f5a2a15e67a4757260d14b1273-2532x1210.png) Thanks to the [driver adapters](https://www.prisma.io/docs/orm/overview/databases/database-drivers#driver-adapters) Preview feature that was recently introduced, developers can now use Prisma ORM with their favorite database drivers from the Node.js ecosystem! Additionally, we have been able to drastically reduce the size of Prisma ORM's query engine so that it now fits into the limited runtime environment of an edge function. ## How to use Prisma ORM in an edge function > 🔬 If you're interested in seeing an example in action, we put together a little [GitHub repository](https://github.com/prisma/nextjs-edge-functions/) demonstrating how to access your database using Prisma ORM with Vercel Edge Functions. > Follow along to learn how to get up and running with Prisma ORM in a **Cloudflare Worker** using a **PlanetScale database** (or [check our docs](https://www.prisma.io/docs/orm/prisma-client/deployment/edge/overview) to use a different combination of edge deployment and database provider). ### 0. Prerequisites Before running through the following steps, make sure you have: - Node.js installed on your machine - a Cloudflare account - a PlanetScale instance up and running and its connection string available ### 1. Set up your application Initialize your project using the [`create-cloudflare-cli`](https://www.npmjs.com/package/create-cloudflare) and follow the steps in the CLI wizard and select the default options for the prompts: ``` copy npm create cloudflare@latest prisma-cloudflare-worker-example -- --type hello-world ``` ### 2. Set up Prisma Navigate into the new directory and install the Prisma CLI: ``` copy cd prisma-cloudflare-worker-example npm install --save-dev prisma ``` Next, initialize Prisma in your project with the following command: ``` copy npx prisma init --datasource-provider mysql ``` The above command: - Created the Prisma schema file in `prisma/schema.prisma` - Created a `.env` file to store environment variables The `.env` file contains a placeholder `DATABASE_URL` environment variable. Update the value with the actual connection string that connects to your PlanetScale database. It may look similar to this: ```bash # .env DATABASE_URL="mysql://USERNAME:PASSWORD@aws.connect.psdb.cloud/DATABASE?sslaccept=strict" ``` > **Note:** The connection string above uses placeholders for the *username*, *password* and *name* of your database. Be sure to replace these with the values for your own database. Update your Prisma schema to look as follows: ```prisma copy generator client { provider = "prisma-client-js" previewFeatures = ["driverAdapters"] } datasource db { provider = "mysql" url = env("DATABASE_URL") relationMode = prisma // required for PlanetScale } model Log { id Int @id @default(autoincrement()) level Level message String meta Json } enum Level { Info Warn Error } ``` The above Prisma schema: - Enables the `driverAdapters` Preview feature flag - Defines a `Log` model and `Level` enum To map your data model to the database, you need to use the `prisma db push` CLI command: ``` copy npx prisma db push ``` This created a new `Log` table in your database that you can now view in the PlanetScale dashboard. ### 3. Write the Cloudflare Worker function In your `wrangler.toml` file, add a `[vars]` key and your database connection string (like before, replace the placeholders for `USERNAME`, `PASSWORD` and `DATABASE` with the values of your own PlanetScale instance): ```toml copy # wrangler.toml name = "prisma-cloudflare-accelerate" main = "src/main.ts" compatibility_date = "2022-11-07" [vars] DATABASE_URL = "mysql://USERNAME:PASSWORD@aws.connect.psdb.cloud/DATABASE?sslaccept=strict" ``` > **Note:** Since this is a demo app, we're adding the plain connection string into `wrangler.toml`. However, as this file is typically committed into version control, you should never do this in production because that would publicly expose your database connection. Instead, use [Cloudflare's configuration for secrets](https://developers.cloudflare.com/workers/configuration/secrets/). Next, install the PlanetScale serverless database driver and its [driver adapter](https://www.prisma.io/docs/orm/overview/databases/database-drivers#serverless-driver-adapters): ``` copy npm install @prisma/adapter-planetscale @planetscale/database ``` Update the example Cloudflare Worker snippet in the `src/index.ts` file with the following code: ```ts copy import { PrismaClient } from '@prisma/client' import { Client } from '@planetscale/database' import { PrismaPlanetScale } from '@prisma/adapter-planetscale' export interface Env { DATABASE_URL: string } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise { const config = { url: env.DATABASE_URL, // see https://github.com/cloudflare/workerd/issues/698 fetch: (url: any, init: any) => { delete init['cache'] return fetch(url, init) }, } const client = new Client(config) const adapter = new PrismaPlanetScale(client) const prisma = new PrismaClient({ adapter }) await prisma.log.create({ data: { level: 'Info', message: `${request.method} ${request.url}`, meta: { headers: JSON.stringify(request.headers), }, }, }) const logs = await prisma.log.findMany({ take: 20, orderBy: { id: 'desc', }, }) console.log(JSON.stringify(logs)) return new Response(JSON.stringify(logs)) }, } ``` Start up the application: ``` copy npm run dev ``` From the terminal output, you can now open the URL pointing to `localhost` or hit the `b` key to open your browser and invoke the Worker function. If everything went well, you'll see output looking similar to this: ```js [{ "id": 1, "level": "Info", "message": "GET http://localhost:63098/", "meta": { "headers": "{}" } }] ``` ### 4. Publish to Cloudflare Workers You can now deploy the application by running the following command: ``` copy npm run deploy ``` This command will deploy your edge function to Cloudflare and output the URL where it can be accessed. ## Try it out and share your feedback We would love to know what you think! Try out the new support for edge deployments using [Vercel](https://www.prisma.io/docs/orm/prisma-client/deployment/edge/deploy-to-vercel) or [Cloudflare](https://www.prisma.io/docs/orm/prisma-client/deployment/edge/deploy-to-cloudflare) and share your feedback with us via [Twitter](https://twitter.com/prisma) or [Discord](http://pris.ly/discord) 🚀 If you run into any issues, you can create a bug report [here](https://github.com/prisma/prisma/issues/new/choose). --- ## [How We're Constantly Improving the Performance of Prisma](/blog/performance-engineering-aeduv0rei0jk) **Meta Description:** No description available. **Content:** > ⚠️ **This article is outdated** as it relates to [Prisma 1](https://github.com/prisma/prisma1) which is now [deprecated](https://github.com/prisma/prisma1/issues/5208). To learn more about the most recent version of Prisma, read the [documentation](https://www.prisma.io/docs). ⚠️ ## Constantly evaluating performance We're taking performance very seriously. Since we started working on Prisma, we have adopted many practices and tools that help us to constantly evaluate and optimize the performance of the software that we build. ### Profiling and benchmarking are part of the engineering process To ensure the _stability_ of our software, we're running a unit test suite every time new features are introduced. This prevents regression bugs and guarantees our softwares behaves in the way it is expected to. Because _performance_ and stability are equally important to us, we're employing similar mechanisms to ensure great performance. With every code change, we're heavily testing performance by running an extensive benchmarking suite. This benchmarking suite is testing a variety of operations (e.g. relational filters and nested mutations) to cover all aspects of Prisma. The results are carefully observed and features are being optimized if needed. Sometimes even minor code changes can have a very negative impact on the performance of an application. Catching these by hand is very difficult, without any sort of profiling tool almost impossible. The benchmarking suite provides an automated way for us to identify such issues and is absolutely crucial to avoid the accidental introduction of performance penalties. ### Using FlameGraphs to identify expensive code paths [FlameGraphs](http://www.brendangregg.com/flamegraphs.html) are an important tool in our profiling activities. We're using them to visualize expensive code paths (in terms of memory or CPU usage) which we can then optimize. FlameGraphs are extremely helpful not only to identify low-hanging fruits for quick performance gains but also to surface problematic areas that are more deeply engrained in our codebase. ### An example how we reduced memory allocation by 40% Here is an example to illustrate how the benchmarking suite and FlameGraphs helped us identify and fix an issue that ultimately led to a 40% reduction in memory allocation for certain code paths. 1. After having introduced a code change, the data of our benchmarking suite showed that a certain code path was notably slowing down as load increased. 2. To identify the part in the code that was causing the performance degrade, we looked into the FlameGraph visualization. 3. The FlameGraph showed that a `Calendar` instance ate lots of memory during the execution of a certain code path (the width of the purple areas indicates how much memory is occupied by the `Calendar`) ![FlameGraph of Calendar instance](https://i.imgur.com/fLCuthZ.png) 4. Further debugging showed that the `Calendar` was instantiated in a _hot path_ which caused the high memory usage. 5. In this case, the fix was simple and the `Calendar` instantiation could just be moved out of the hot path. 6. The fix reduced the memory allocation by 40%. To learn more about the details of this issue, you can check out the [PR](https://github.com/prismagraphql/prisma/pull/2800) that fixed it. > Keep the eyes open for our **engineering blog**. The articles on the engineering blog will focus in extensive detail on our performance optimizations and other deeply technical topics. ## Increasing performance in Prisma 1.14 With the latest `1.14` and `1.15-beta` releases of Prisma, we're introducing a number of concrete performance improvements. Those improvements are the result of a period where we heavily invested into identifying the most expensive parts in our software and optimizing them as much as possible. A common pattern we're seeing in our opimization activities is that it is a lot more time consuming to _identify_ the exact part in the codebase causing a performance penalty than actually _fixing_ it (which often is with done minimal changes to the code). The above example with the `Calendar` instance is a good illustration of that. If you're curious, here's a few more PRs that brought notable performance gains through rather little changes to our codebase: - [Only read visible fields from result set](https://github.com/prismagraphql/prisma/pull/2805) - [Improve relation filter query](https://github.com/prismagraphql/prisma/pull/2771) - [Cache some of the sangria work](https://github.com/prismagraphql/prisma/pull/2814) - [Use unsorted map for RootGCValue](https://github.com/prismagraphql/prisma/pull/2804) - [Do not use deferreds for single item query](https://github.com/prismagraphql/prisma/pull/2807) ## Future performance improvements Our vision to bu ild a data layer that uses GraphQL as a universal abstraction for all databases is a technically extremely ambitious goal. Some benefits of this are: Easy data access on the application layer (similar to an ORM but without limitations), simple data modeling and migrations, out-of-the-box realtime layer for your database (similar to RethinkDB), cross-database workflows and a lot more. These benefits provide enormous productivity boosts in modern application development and are impossible to achieve without a dedicated team focused on building such a data layer _full-time_. Working on this project as a company, enables us to heavily invest in **specialized optimization techniques** that product-focused companies could never afford to manually build into their data access layer. In upcoming releases, we're planning to work on new features specifically designed for better performance. This includes a **smart caching system**, support for **pre-computed views** as well as **support for many more databases** each with their own strengths and query capabilities.

--- ## [Fullstack App With TypeScript, PostgreSQL, Next.js, Prisma & GraphQL: Deployment](/blog/fullstack-nextjs-graphql-prisma-5-m2fna60h7c) **Meta Description:** Learn how to build a fullstack app using TypeScript, PostgreSQL, Next.js, GraphQL and Prisma. In this article you are going to deploy your app to Vercel **Content:** ## Table of Contents - [Introduction](#introduction) - [Prerequisites](#prerequisites) - [Fork the repository](#fork-the-repository) - [Database access in serverless environments with the Prisma Data Proxy](#database-access-in-serverless-environments-with-the-prisma-data-proxy) - [Getting started with the Prisma Data Proxy](#getting-started-with-the-prisma-data-proxy) - [Update the application](#update-the-application) - [Enable the Prisma Data Proxy](#enable-the-prisma-data-proxy) - [Create new scripts in `package.json`](#create-new-scripts-in-packagejson) - [Deploy the app to Vercel](#deploy-the-app-to-vercel) - [Summary](#summary) ## Introduction In this course you will learn how to build "awesome-links", a fullstack app where users can browse through a list of curated links and bookmark their favorite ones. In [part 4](/fullstack-nextjs-graphql-prisma-4-1k1kc83x3v), you added support for image uploads using AWS S3. In this part, you will set up the Prisma Data Proxy to handle database connections in a serverless environment and then deploy the app to Vercel. ## Prerequisites To follow along with this tutorial, you will need an account on [GitHub](https://github.com) and a [Vercel](https://vercel.com). You will also need a hosted PostgreSQL database. ## Fork the repository You can find the [complete source code](https://github.com/prisma/awesome-links) for the course on GitHub. To follow along, fork the repository to your own GitHub account. If you're following along from the previous parts, ensure you have added your code to source control and pushed it to GitHub. ## Database access in serverless environments with the Prisma Data Proxy Serverless functions are ephemeral and short-lived – _stateless_. When traffic to your application spikes, the number of instances of a serverless function also goes up. On the other hand, database connections are stateful and require a TCP connection between the application and the database. When a serverless function needs to access a database, it establishes a connection to it, submits a query, and receives the response from the database. The response data is then delivered to the client that invoked the serverless function, the database connection is closed and the function is torn down again. When there's a traffic spike, each serverless function will spawn a new database connection. ![](https://imgur.com/9OuYJ08.png) Traditional databases such as PostgreSQL and MySQL typically have a _database connection limit_ that can be easily exhausted when there's a traffic spike to your application. When the connection limit is exhausted, the requests to your application would start failing. A solution to this problem is using a database connection pooler, such as [pgBouncer](https://www.pgbouncer.org/) for PostgreSQL or the [Prisma Data Proxy](https://www.prisma.io/docs/data-platform/data-proxy). The Prisma Data Proxy is a proxy server for your database that manages a connection pool and ensures existing database connections are reused. This prevents incoming user requests from failing and improves your app's performance. ## Getting started with the Prisma Data Proxy Go to [https://cloud.prisma.io/projects/create](https://cloud.prisma.io/projects/create) and log in using GitHub. In the "Create project" page, paste in your database's connection string to connect your project to the database. If your database is behind a Static IP, enable the feature in the "Static IP" section. Once you're done, click **Create project**. ![Connecting your project to your application database](/blog/posts/fullstack-nextjs-graphql-prisma-5/create-project.png) Once your project is created, you should be redirected to the "Get started" page. You can connect your project to your GitHub repository in the "Enable schema synchronization" section, however, it's completely optional. ![Connect your project to your GitHub repository](/blog/posts/fullstack-nextjs-graphql-prisma-5/schema-sync.png) To create a Data Proxy connection string, click the **Create a new connection string** button in the "Create a Data Proxy new connection string" section. Give your connection string a name and click **Create** once you're ready. ![Connect your project to your GitHub repository](/blog/posts/fullstack-nextjs-graphql-prisma-5/create-a-data-proxy-connection-string.png) ![Connect your project to your GitHub repository](/blog/posts/fullstack-nextjs-graphql-prisma-5/data-proxy-connection-string-modal.png) Copy the Prisma Data Proxy URL as you won't be able to see it again, but you can create more later. ![Connect your project to your GitHub repository](/blog/posts/fullstack-nextjs-graphql-prisma-5/data-proxy-connection-string.png) ## Update the application Before you deploy the application, you will make a few changes. ### Enable the Prisma Data Proxy Before you deploy your application, you will need to make a few updates to your application to make it work with the Prisma Data Proxy. First, update your `.env` file by renaming the existing `DATABASE_URL` to `MIGRATE_DATABASE_URL`. Create a `DATABASE_URL` variable and set the Prisma Data Proxy URL from the previous step here: ``` # .env MIGRATE_DATABASE_URL="postgres://" DATABASE_URL="prisma://" ``` The `MIGRATE_DATABASE_URL` will be used for making database schema changes to your database. ### Create new scripts in `package.json` Next, update your `package.json` file by adding a `vercel-build` script: ```json "scripts": { //... existing scripts "vercel-build": "npx prisma generate --data-proxy && next build", }, ``` The `vercel-build` script will generate Prisma Client that uses the Prisma Data Proxy and build the application. ## Deploy the app to Vercel Log in to your Vercel account and create a new project by clicking **New Project**. ![Creating a new project on Vercel](/blog/posts/fullstack-nextjs-graphql-prisma-5/vercel-new-project.png) Next, import the "awesome-links" repository. ![Importing a Git repository](/blog/posts/fullstack-nextjs-graphql-prisma-5/vercel-import-project.png) Finally, add your environment variables. Refer to the `.env.example` file in the repository for the environment variables. > **Note**: Make sure that you are using the Data Proxy connection string when setting the `DATABASE_URL` environment variable. Once you've added the environment variables, click **Deploy**. ![Configuring environment variables](/blog/posts/fullstack-nextjs-graphql-prisma-5/vercel-environment-variables.png) Once your application is successfully deployed, copy its URL and: - Update the **Allowed Callback URLs** and **Allowed Logout URLs** on the Auth0 Dashboard with the URL of your application - Update your Auth0 Action with the URL of the deployed application - Update the **AllowedOrigins** Cross-origin Resource Sharing (CORS) policy on S3 with the URL to your deployed application - Update the `AUTH0_CALLBACK_URL` environment variable with the URL of your deployed application - Redeploy the application to production If everything works correctly, you will be able to view your deployed application. ## Summary This article concludes the series. You learned how to build a full-stack app using modern tools that offer great developer experience and leveraged different services to get your application production-ready. You: - Explored database modeling using Prisma - Built a GraphQL API using GraphQL Yoga and Pothos - Added authentication using Auth0 - Added image upload using AWS S3. - Used the Prisma Data Proxy to handle database connection pooling - Deployed your Next.js application to Vercel You can find the complete source code for the app on [GitHub](https://github.com/prisma/awesome-links). Feel free to raise issues or contribute to the repository if you find any bugs or want to make improvements. Feel free to reach out on [Twitter](https://twitter.com/thisismahmoud_) if you have any questions. --- ## [Improve your application’s performance with AI-driven analysis and recommendations](/blog/optimize-now-generally-available) **Meta Description:** Enhance database performance with Prisma Optimize's AI-powered query insights. **Content:** ## Query performance: Now simple enough to improve on your lunch break You’ve built an app that runs perfectly during development, but once it goes live, things slow down. Pages lag, specific queries drag, and identifying the root cause feels like a guessing game. Is it an unindexed column? A query returning too much data? Manually combing through logs can take hours, especially without the right tools to spot the issue. **How Prisma Optimize solves this:** Prisma Optimize takes the guesswork out of query troubleshooting. It automatically identifies problematic queries, highlights performance bottlenecks, and provides actionable recommendations. You can also track the impact of optimizations in real-time, allowing you to focus on building your app while Prisma Optimize helps you fine-tune performance. ## Streamlined query insights and optimization Fast database queries are critical for app performance, but tracking down slow queries and fixing them can be complex. Prisma Optimize simplifies this process by: - Automatically surfacing problematic queries. - Offering key performance metrics and targeted improvement suggestions. - Providing insights into raw queries for deeper analysis. With Prisma Optimize, you can optimize your database without needing complex setups or additional infrastructure. ## Get performance metrics and see the raw query Prisma Optimize lets you create [recordings](https://www.prisma.io/docs/optimize/recordings?utm_campaign=optimize-ga&utm_source=website&utm_medium=blogpost) from app runs and view query latencies: ![A recording consisting of query performance insights](https://cdn.sanity.io/images/p2zxqf70/production/a36715bc4afcf3eddde3815636ed7a1ed012c7d5-1497x490.png) You can also click on a specific query to view the generated raw query, identify errors, and access more comprehensive performance insights: ![A recording consisting of a more comprehensive query performance insights](https://cdn.sanity.io/images/p2zxqf70/production/67916e1c4522a8994edaf4b75c47030b50f3ee4e-1497x644.png) ## Expert recommendations to improve your queries Prisma Optimize provides actionable recommendations to enhance query performance, saving you hours of manual troubleshooting. Current recommendations include (and more on the way): - **Excessive number of rows returned:** Reduces load by limiting unnecessary data retrieval. - **Query filtering on an unindexed column:** Identifies where indexing will improve performance. - **Full table scans caused by `LIKE` operations:** Suggests more efficient alternatives when inefficient operators are detected in queries. You can compare query latencies across different recordings to evaluate performance improvements after applying these recommendations: ![Comparing performance after applying the recommendations provided by optimize](https://cdn.sanity.io/images/p2zxqf70/production/3e399b441533267eb607869ff0be34162b175b23-1816x586.gif) ### Interacting with Prisma AI for further insights from each recommendation Click the **Ask AI** button in any recommendation to interact with [Prisma AI](https://www.prisma.io/docs/optimize/prisma-ai?utm_campaign=optimize-ga&utm_source=website&utm_medium=blogpost) and gain additional insights specific to the provided recommendation: ![GIF of an interaction with Prisma AI chatbot to gain more insights on a specific recommendation](https://cdn.sanity.io/images/p2zxqf70/production/8a49d78ed717ef163ffb6927acc80362c00e1055-754x706.gif) ## Try out the example apps Explore our [example apps](https://github.com/prisma/prisma-examples/tree/latest/optimize) in the Prisma repository to follow along and optimize query performance using Prisma Optimize: | Demo | Description | | --- | --- | | [`starter`](https://github.com/prisma/prisma-examples/tree/latest/optimize/starter) | A Prisma Optimize starter app | | [`optimize-excessive-rows`](https://github.com/prisma/prisma-examples/tree/latest/optimize/optimize-excessive-rows) | An example app demonstrating the "Excessive number of rows returned" recommendation provided by Optimize. | | [`optimize-full-table-scan`](https://github.com/prisma/prisma-examples/tree/latest/optimize/optimize-full-table-scan) | An example app demonstrating the "Full table scans caused by `LIKE` operations" recommendation provided by Optimize. | | [`optimize-unindexed-column`](https://github.com/prisma/prisma-examples/tree/latest/optimize/optimize-unindexed-column) | An example app demonstrating the "Query filtering on an unindexed column" recommendation provided by Optimize. | ## Start optimizing your queries Get started with Prisma Optimize today and see the improvements it brings to your query performance. Stay updated with the latest from Prisma via [X](https://x.com/prisma) or our [changelog](https://www.prisma.io/changelog). Reach out to our [Discord](https://pris.ly/discord) if you need support.


--- ## [Announcing Tweets for Trees](/blog/tweets-for-trees-arboreal) **Meta Description:** With Earth Day coming up on the 22nd, Prisma will be planting a tree for every tweet about Prisma we see in April **Content:** As we enter into April of 2021 in some of the most eventful years of our lifetime, we wanted to do something a little different to celebrate the spring time 🌸. Since Prisma started, being eco-friendly has been something that we've [valued internally](https://prisma.io/about) and now we're excited to invite our community to join in to our effort! ![Heading to the Berlin climate strike in 2019](/blog/posts/climatestrike1.jpg) With the recent release of Prisma [Migrate](https://www.prisma.io/blog/prisma-migrate-ga-b5eno5g08d0b), all three aspects (Client, Migrate, and Studio) of Prisma are production ready. We've loved seeing what people have been writing and [posting on Twitter](https://twitter.com/prisma/likes), and we thought we could use the opportunity to do something more. **With [Earth Day](https://www.earthday.org/) 🌍 coming up on the 22nd, Prisma will be planting a tree for every tweet about Prisma we see in April.** We're calling this initiative **#TweetsForTrees**. Every tweet tagging [@prisma](https://twitter.com/prisma) in the month of April will be eligible. ## How It Works - In the month of April, the sharp sleuths at Prisma, will be on the lookout for tweets about Prisma. For any tweets containing "@prisma", we will reply with a 🌳 emoji, as long as it doesn't disturb the flow of the conversation. Otherwise, we'll just count it and get the tree quietly 🤩 - Weekly, we'll round up all of the tweets that we found and order that number of trees through [Tree-Nation](https://tree-nation.com/) - We'll then let everyone know how many trees we've planted at the end of each week this month - We'll just be counting original tweets that contain @prisma, rather than any conversation that includes @prisma in the replies ## How you can join in ✅ - Spread the word about Prisma, and tweet using the Prisma username. Some exciting recent announcements include: - The [Migrate GA](https://www.prisma.io/blog/prisma-migrate-ga-b5eno5g08d0b) - The [Prisma Studio GA](https://www.prisma.io/blog) - Any of the new [Prisma releases](https://github.com/prisma/prisma) (in the month of April we expect to release Prisma 2.21, and 2.22) - You can also see all of the exciting new releases and updates that happened this quarter in our [summary blog post](https://www.prisma.io/blog/whats-new-in-prisma-q1-2021-spjyqp0e2rk1) - Help us spot any tweets we've missed. You can ping us directly when people reference Prisma. As this is a year, where we can only connect virtually 📺 and see each other through the screen, we're excited to make a greater impact beyond our desks! We're looking forward to seeing what a change we can make in the world together! 🌳 💚 --- ## [Prisma Products Are Now Available on AWS Marketplace](/blog/aws-marketplace) **Meta Description:** AWS Marketplace customers can purchase Prisma products through AWS Marketplace. **Content:** We're excited to announce that Prisma Accelerate is [now available](https://aws.amazon.com/marketplace/pp/prodview-2a2vc6mafcsg4) on the Amazon Web Services (AWS) Marketplace. It is now easier than ever for development teams who use AWS to now be able to also buy Prisma's products via a familiar purchasing and billing interface. ## Advantages of Choosing Prisma through AWS Marketplace Teams opting for Prisma via AWS Marketplace can enjoy several key benefits: 1. **Streamlined Procurement**: Pay for Prisma products directly through your existing AWS account, simplifying the purchasing process. 2. **Unified Billing**: Incorporate Prisma costs into your AWS invoice, facilitating easier financial management and reporting. 3. **Faster Development**: Utilize Prisma's advanced features alongside AWS's comprehensive suite of services to speed up your development cycles. 4. **Meet your AWS spend commitments:** Prisma products purchased through the AWS Marketplace contribute to your AWS spend, helping you reach your commitments more quickly. ## Kickstarting Your Journey with Prisma on AWS Ready to transform your database management with Prisma on AWS? Here's how to get started: 1. Navigate directly to the [listing on AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-2a2vc6mafcsg4) 2. Choose the plan that best fits your organization's needs 3. Follow the straightforward setup process to integrate Prisma within your application As we continue to innovate and expand our offerings, [availability on AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-2a2vc6mafcsg4) represents a significant leap forward in our mission to make database management more accessible and efficient for developers across all company sizes and geographies. ### Frequently Asked Questions #### How do I switch to AWS billing if I am already a customer? **A:** Please send us a message at [support@prisma.io](mailto:support@prisma.io) and we will help with the switch. #### What are the benefits of purchasing through AWS Marketplace? **A:** Purchasing through AWS Marketplace allows you to consolidate your billing with other AWS services, potentially simplify procurement processes, and may offer tax benefits depending on your location and business structure. #### Will I receive the same level of support if I purchase through AWS Marketplace? **A:** Yes, you will receive the same level of support and access to all features as customers who purchase directly from Prisma. #### Is there a difference in features or functionality when purchasing through AWS Marketplace? **A:** No, you will have access to the same features and functionality as if you had purchased directly from Prisma. #### How does pricing compare between AWS Marketplace and direct purchase? **A:** The pricing for our products on AWS Marketplace is consistent with our direct pricing. However, because you are paying annually, there’s a 10% discount built into the annual pricing and for ongoing usage, if you are on the Pro plan, you get the Business plan usage pricing. #### Can I purchase Prisma products through AWS Marketplace if I'm not in the United States? **A:** AWS Marketplace is available in many countries. Please check AWS Marketplace availability in your region or contact our sales team for more information. #### How do I manage my Prisma subscription after purchasing through AWS Marketplace? **A:** While billing will be handled through AWS, you will still manage your Prisma account and services through the Prisma Data Platform interface. #### Which Prisma Data Platform plans are available on AWS Marketplace? **A:** You can purchase the Pro and Business plans on AWS Marketplace as public offers. If you are interested in Private offers, please follow the outlined process within AWS Marketplace. Note that even though the Pro and Business plans are annual on AWS Marketplace, usage is still billed on a monthly basis. #### Do you offer a free trial through AWS Marketplace? **A:** There is no free trial when purchasing through AWS Marketplace, but you can still do a free trial by signing up directly on Prisma Data Platform and then elect to pay via AWS Marketplace once your testing is over. #### Can I upgrade or downgrade my plan once I have subscribed? **A:** Since you will make an annual purchase, downgrading is not possible automatically. However, we are more than happy to help through the process. Just ping us at [support@prisma.io](mailto:support@prisma.io). #### Do I need to host anything on AWS to make the purchase through AWS Marketplace? **A:** No, only billing will route through AWS Marketplace. You will still manage your account on the Prisma Data Platform and all resources are deployed and managed automatically by the Prisma Data Platform. No additional infrastructure is required to be set up by you. --- ## [Prisma Raises $12M to Build the Next Generation of Database Tools](/blog/prisma-raises-series-a-saks1zr7kip6) **Meta Description:** No description available. **Content:** ## Contents - [Our mission: Making databases easy](#our-mission-making-databases-easy) - [Where we are today](#where-we-are-today) - [What's next for Prisma](#whats-next-for-prisma) - [We 💚 our community](#we--our-community) --- ## TLDR At Prisma, our goal is to **revolutionize how application developers work with databases**. Considering the [vast number of different databases](https://www.prisma.io/dataguide/intro/comparing-database-types) and [variety of tools](https://www.prisma.io/dataguide/types/relational/comparing-sql-query-builders-and-orms) for working with them, this is an extremely ambitious goal! We are thrilled to enter the next chapter of pursuing this goal with a **$12M Series A** funding round led by [Amplify Partners](https://amplifypartners.com/). We are especially excited about this partnership as Amplify is an experienced investor in the developer tooling ecosystem and has led investments for numerous companies, such as [Datadog](https://www.datadoghq.com/), [Fastly](https://www.fastly.com/), and [Gremlin](https://www.gremlin.com/). --- ## Our mission: Making databases easy ### Database tools are stuck with legacy paradigms Despite having been developed in the 1970s, relational [databases](https://www.prisma.io/dataguide/intro/what-are-databases) are still the most commonly used databases today. While [other database types have been developed in the meantime](https://www.prisma.io/dataguide/intro/comparing-database-types), from _document_, to _graph_, to _key-value_ databases, working with databases remains one of the biggest challenges in application development. While almost any other part of the development stack has been modernized, database tools have been stuck with the same paradigms for the last decades. ![Progression of the development stack](https://imgur.com/WwMdROo.png) When working with relational databases, developers have the choice of working directly with SQL or using a higher-level abstraction called ORMs. [None of these options is particularly compelling](https://www.prisma.io/docs/concepts/overview/why-prisma#problems-with-sql-orms-and-other-database-tools). Using SQL is very low-level, resulting in reduced developer _productivity_. In contrast, ORMs are too high-level and developers sacrifice _control_ over the executed database operations when using this approach. ORMs further suffer from a fundamentally misguided abstraction called the [object-relational impedance mismatch](http://blogs.tedneward.com/post/the-vietnam-of-computer-science/). ### Prisma modernizes how developers work with databases Similar to how React.js modernized frontend development or how Serverless invented a new model for compute infrastructure, **Prisma is here to bring a new and modern approach for working with databases**! Prisma's unique approach to solving database access with a _generated_ query builder that's fully type-safe and can be tailored to any database schema sets it apart from previous attempts of solving the same problem. A big part of the modernization comes from our **major focus on developer experience**. Database tools are often associated with friction, uncertainty, painful hours of debugging and costly performance bottlenecks. **Developer experience is part of our DNA at Prisma.** Working with databases is too often associated with friction and uncertainty when it should be fun, delightful and productive! We want to make working with databases _fun_, _delightful_ and _productive_ while guiding developers towards proper patterns and best practices in their daily work with databases! ### Learning from our past: From GraphQL to databases As a company we've gone through a number of major product iterations and pivots over the last years. ![Path from Graphcool to Prisma 2](https://imgur.com/4YPWyaW.png) Our initial products, Graphcool and Prisma 1 were focused on [GraphQL](http://graphql.org/) as a technology. However, as we were running both tools in production, we realized they didn't address the _core_ problems developers had. We realized that a lot of the value we provided with both tools didn't necessarily lie in the quick provision of a GraphQL server, but rather in the fact that developers didn't need to manage their _database workflows_ explicitly. This realization led to a pivot which ultimately manifested in the rewrite to Prisma 2. With this new version of Prisma, we have found the right level of abstraction that ensures developers keep full control and flexibility about their development stack while not needing to worry about database workflows! ### Inspired by the data layers of big companies (Twitter, Facebook, ...) The approach Prisma takes for this modernization is inspired by big tech companies such as Twitter, Facebook, or Airbnb. To ensure productivity of application developers, it is a common practice in these organizations to introduce a _unified data access layer_ that abstracts away the database infrastructure and provides developers with a more familiar and convenient way of accessing data. Facebook developed a system called [TAO](https://medium.com/coinmonks/tao-facebooks-distributed-database-for-social-graph-c2b45f5346ea) that fulfills the data needs of application developers. Twitter has built a "virtual database" called [Strato](https://about.sourcegraph.com/graphql/graphql-at-twitter#schema) which _brings together multiple data sources so that they can be queried and mutated uniformly_. Airbnb [combines GraphQL and Thrift](https://medium.com/airbnb-engineering/reconciling-graphql-and-thrift-at-airbnb-a97e8d290712) to abstract away the implementation details of querying data. ![How facebook, twitter, airbnb approach databases](https://imgur.com/Hb9VOWN.png) Building these custom data access layers requires _a lot_ of time and resources (as these are typically implemented by dedicated _infrastructure teams_) and thus is not a realistic approach for most companies and development teams. Being based on the same core ideas and principles as these systems, **Prisma democratizes the pattern of a uniform data access layer** and makes it accessible as an open-source technology for development teams of all sizes. --- ## Where we are today ### Prisma 2.0 is ready for production After running Preview and Beta versions for more than a year, we've recently [launched Prisma 2.0 for production](https://www.prisma.io/blog/announcing-prisma-2-n0v98rzc8br1). Having rewritten the core of Prisma from Scala to Rust for the transition, we've built a strong foundation to expand the Prisma toolkit to cover various database workflows in the future. Prisma's main feature is [Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client), an auto-generated and type-safe query builder which can be used to access a database in Node.js and TypeScript. Thanks to [introspection](https://www.prisma.io/docs/concepts/components/introspection), Prisma Client can be used to work with any existing database! > **Note**: Prisma currently supports **PostgreSQL**, **MySQL** and **SQLite** databases – with more planned. Please create [new GitHub issues](https://github.com/prisma/prisma/issues/new) or subscribe to existing ones (e.g. for [MongoDB](https://github.com/prisma/prisma/issues?q=is%3Aissue+is%3Aopen+mongo) or [DynamoDB](https://github.com/prisma/prisma/issues/1676)) if you'd like to see support for specific databases. ### Next-generation web frameworks are built on Prisma The Node.js ecosystem is known for lots of different frameworks that try to streamline workflows and prescribe certain conventions. We are extremely humbled that many framework authors decide to use Prisma as their data layer of choice. #### Redwood.js: Bringing full-stack to the Jamstack The new [RedwoodJS](https://redwoodjs.com/) framework by GitHub co-founder [Tom Preston-Werner](https://twitter.com/mojombo) seeks to become the "Ruby on Rails" equivalent for Node.js. RedwoodJS is based on React and GraphQL and comes with a baked-in deployment model for serverless functions. #### Blitz.js: The Fullstack React Framework Another framework with increasing anticipation and excitement in the community is [Blitz.js](http://blitzjs.com/). Blitz is built on top of Next.js and takes a fundamentally different approach compared to Redwood. Its goal is to completely eliminate the API server and ["bring back the simplicity of server rendered frameworks"](https://github.com/blitz-js/blitz/blob/canary/rfc-docs/01-architecture.md#introduction). #### Nexus: A delightful GraphQL application framework At Prisma, we're huge fans of GraphQL and believe in its bright future. That's why we founded the [Prisma Labs](https://github.com/prisma-labs/) team, which dedicates its time to work on open source tools in the GraphQL ecosystem. It is currently focused on building [Nexus](https://www.nexusjs.org/#/), a delightful application framework for developing GraphQL servers. As opposed to RedwoodJS, Nexus is a _backend-only_ GraphQL framework and has no opinions on how you access the GraphQL API from the frontend. ## What's next for Prisma ### Database migrations with Prisma Migrate Database migrations are a common pain point for many developers! Especially with applications running in production, it is often unclear what the best approach is to perform schema changes (e.g. in CI/CD environments). Many developers resort to manual migrations or custom scripts, making the process brittle and error-prone. [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate) is our solution to this problem. Prisma Migrate lets developers map the declarative [Prisma schema](https://www.prisma.io/docs/concepts/components/prisma-schema) to their database. Under the hood, Prisma Migrate generates the required SQL statements to perform the migration. > **Note**: Prisma Migrate is currently in an experimental state and should not be used in production environments. ### Prisma Studio: A visual editor for your database workflows [Prisma Studio](https://www.prisma.io/docs/concepts/components/prisma-studio) is your visual companion for various database workflows. It provides a modern GUI that lets you view and edit the data in your database. You can switch between the _table_ and the _tree_ view, the latter is especially convenient to drill deeply into nested data (explore the two views using the tabs below or try out the [online demo](https://prisma.studio/)). ![Table view visual editor](https://imgur.com/Fc7BweP.png) ![Tree view visual editor](https://imgur.com/kuwS06d.png) > **Note**: Prisma Studio is currently in an experimental state and should not be used in production environments. . ### Beyond Node.js & TypeScript: Prisma Client in other languages Prisma Client is a thin, language-specific layer that delegates the heavy-lifting of query planning and execution to Prisma's [query engine](https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine). The query engine is [written in Rust](https://github.com/prisma/prisma-engines) and runs as a standalone process alongside your main application. This architecture enables us to expand Prisma Client to other languages and bring its benefits to developers beyond the Node.js community. We are already working on **Prisma Client in Go** with a first [alpha version](https://github.com/prisma/prisma-client-go) ready to try out! ### Supporting a broad spectrum of databases and other data sources Prisma is designed in a way that it can potentially connect to _any_ existing data source as long as there is the right _connector_ for it! As of today, we've built connectors for PostgreSQL, MySQL and SQLite. A [connector for MongoDB](https://github.com/prisma/prisma/issues/1277) is already in the works and more are planned for the future. ![Prisma supporting a broad spectrum of databases and other data sources](https://imgur.com/PQSljF7.png) ### Building commercial services to sustain the OSS tools We are committed to building world-class open-source tools to solve common database problems of application developers. To be able to sustain our open-source work, we're planning to build commercial services that will enable development teams and organizations to collaborate better in projects that are using Prisma. > **Note**: The plans for commercial services do not affect the open-source tools we are building, those will remain free forever. --- ## We 💚 our community We are incredibly grateful for everyone who has accompanied us on our journey! It is fantastic to see our lively community on [Slack](https://slack.prisma.io), [GitHub](https://github.com/prisma/prisma), [Twitter](https://twitter.com/search?q=%40prisma&src=typed_query&f=live) and a lot of other channels where folks are chatting about Prisma and helping each other out! ### Join us at Prisma Day If you've become curious about Prisma and want to learn more, be sure to check out our online [**Prisma Day**](https://www.prisma.io/day) conference that will be happening over the next two days! Be sure to tune in and hear from great speakers like [Tom Preston-Werner](https://twitter.com/mojombo) (GitHub co-founder & RedwoodJS author), [Matt Billmann](https://twitter.com/biilmann) (Netlify CEO) and lots of Prisma team members for interesting talks and a lot of fun! ### Get started with Prisma To try Prisma, you can follow the Quickstart or set up Prisma with your own database.
--- ## [How Prisma and GraphQL fit together](/blog/prisma-and-graphql-mfl5y2r7t49c) **Meta Description:** No description available. **Content:** ## TLDR: GraphQL is one of many use cases for Prisma We love GraphQL and strongly believe in its bright future! We will keep investing into the GraphQL ecosystem and strive to make Prisma the best tool for building database-backed GraphQL servers. One example of our efforts is the upcoming [Yoga2](https://github.com/prisma/yoga2) framework which will enable a [_Ruby-on-Rails_-like experience](https://rubyonrails.org/doctrine) for GraphQL. Prisma is an ORM replacement that has many more use cases beyond GraphQL, such as building [REST](https://github.com/prisma/prisma-examples/tree/master/typescript/rest-express) or [gRPC](https://github.com/prisma/prisma-examples/tree/master/typescript/grpc) APIs. **Prisma's goal is to simplify database workflows.** Think of it as a suite of database tools to ease _database access_, _migrations_ and _data management_. --- ## History: From GraphQL to ORMs & databases Let's start with a short history lesson and revisit how Prisma evolved to what it is today. ![GraphQL to ORMs](https://i.imgur.com/ykahwzh.png) ### 1) Graphcool: Making GraphQL easy for frontend developers Before the launch of Prisma and the [official rebranding](https://www.prisma.io/blog/prisma-raises-4-5m-to-build-the-graphql-data-layer-for-all-databases-663484df0f60), our core product used to be Graphcool (an open-source GraphQL BaaS). From the very beginning, the goal of Graphcool was to make it as easy as possible for developers to use GraphQL. The architecture was simple since Graphcool represented the entire backend stack. It included the database, application layer and GraphQL API: ![Graphcool is the entire backend: Database, application layer and GraphQL API](https://i.imgur.com/Felin65.png) After running Graphcool in production for two years, we've noticed the following recurring customer feedback and requests: - Graphcool was _loved_ for its ease-of-use. Developers used it for prototyping but then often dropped it in production in favor of building their own GraphQL servers. - Developers wanted more control and flexibility in their backend stack, for example: - Decoupling the database from the API layer - Defining their own domain-driven GraphQL schemas (instead of generic CRUD) - Flexibility in choosing programming languages, frameworks, testing & CI/CD tools ### 2) Prisma bindings: Build a GraphQL server with any database It was clear that the requirements developers have for building sophisticated GraphQL backends weren't met by a tool like Graphcool. This realization led us to Prisma. The first version of Prisma was a standalone version of Graphcool's _query engine_ component. By making Prisma available as a standalone component, we gave developers the opportunity to quickly generate a CRUD GraphQL API for their database. This API was not to be consumed from the frontend. Instead, the idea was to build an additional application layer on top of it to add business logic and customize the client-facing API. This application layer was implemented using _Prisma bindings_. The mental model required developers to understand that they were dealing with two GraphQL APIs (a custom client-facing API on top of a generated CRUD API): ![When working with Prisma bindings, developers need to understand the concept of two GraphQL APIs](https://i.imgur.com/NS0YFih.png) While the primary goal of Prisma still was to make it as easy as possible for developers to use GraphQL, the focus had shifted to becoming a _data access layer_ that connects your GraphQL resolvers with a database. ### 3) Prisma client: Replacing traditional ORMs After talking to lots of customers and the Prisma community, our understanding of what Prisma was (and could eventually become) had again evolved quite a bit. The prior approach of building GraphQL servers with Prisma bindings had a few issues: - While Prisma bindings made it easy to get started, the complexity of the concepts developers needed to understand in more advanced use cases went through the roof (due to the intricacies of [schema delegation](https://www.prisma.io/blog/graphql-schema-stitching-explained-schema-delegation-4c6caf468405) and the [`info`](https://www.prisma.io/blog/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a) object). - Very difficult and impractical to achieve fully type-safe resolvers. - Limited to the JavaScript ecosystem. - Limited to GraphQL as a use case. The [Prisma client](https://www.prisma.io/blog/prisma-client-preview-ahph4o1umail) solves these issues. It is an auto-generated database client with a simple and fully type-safe data access API. With this new approach, the generated CRUD GraphQL API is not part of the core Prisma development workflows any more. It rather becomes an _implementation detail_: ![Simplified mental model: Developers only need to understand the Prisma client API](https://i.imgur.com/I9D33PU.png) Note that very soon there will be a version of Prisma that can be used right inside your application server, omitting the need for the extra Prisma server: ![The upcoming Prisma 2 will enable running Prisma without an extra server](https://i.imgur.com/wDONhZ6.png) While we believe that the Prisma client API today already is one of the best data access APIs out there, a lot of community feedback helped us improving it even further. The result is an extremely powerful and intuitive database API that we'll release soon. Because the Prisma client has a built-in [dataloader](https://github.com/facebook/dataloader), it's the perfect tool to implement the resolvers in a GraphQL server. --- ## How to think about Prisma's generated GraphQL API Understanding that the generated Prisma GraphQL CRUD API is considered an implementation detail is crucial to comprehend Prisma's focus and future direction. ### From a declarative datamodel to generated GraphQL CRUD The core idea of Prisma was always the same: 1. Developers define their datamodel in GraphQL SDL and map it to their database 1. Prisma generates a powerful CRUD GraphQL API based on the datamodel 1. The generated CRUD GraphQL API is used as foundation for the application layer and the client-facing API (_except with Graphcool_) While the generated CRUD GraphQL API was absoutely essential with Prisma bindings, it has become an implementation detail with the Prisma client. This is also reflected in the latest redesign of the [Prisma website](https://www.prisma.io), where the Prisma client has replaced GraphQL as the dominant theme: ### De-emphasizing Prisma's CRUD GraphQL API Today, developers shouldn't care about _how_ the Prisma client talks to the underlying database. **What developers should care about is the Prisma client API!** To reflect this in our official documentation, we have removed the Prisma GraphQL API docs in the last Prisma release. If you still need the documentation, you can access it by navigating to [older Prisma versions in the docs](https://v1.prisma.io/docs/1.27/prisma-graphql-api). We also just introduced Prisma Admin as an additional tool to interact with the data in your Prisma project (in addition to the GraphQL Playground). ### Data modelling in GraphQL SDL Another common source of confusion in regards to Prisma and GraphQL can be data modelling. When using Prisma, the datamodel is specified using a subset of GraphQL's schema definition language (SDL). While we've already adjusted the file type of the datamodel from `.graphql` to `.prisma`, using SDL for data modelling is still a strong tie to GraphQL. However, we are currently working on our own model language (which will be a modified version of SDL). ### Comparing Prisma to AWS AppSync & Hasura With the new understanding of the role of Prisma's CRUD GraphQL API, it becomes clear that Prisma is not in the category of "GraphQL-as-a-Service" anymore. Tools like [AWS AppSync](https://aws.amazon.com/appsync/) and [Hasura](https://hasura.io/) provision a generated GraphQL API for your database (or in the case of AppSync also other data sources). In contrast, Prisma enables simplified and type-safe database access in various languages. --- ## GraphQL is an important use case for Prisma Since the Prisma client was released, it's considered an implementation detail that Prisma uses GraphQL under the hood. So what role does GraphQL then play for Prisma? ### We love GraphQL The answer is clear to us: We still see GraphQL as one of the most important upcoming API technologies and want to make it as easy as possible for developers to build GraphQL servers. GraphQL remains to be an important Prisma use case for Prisma! ### Investing into the GraphQL ecosystem We will keep investing in the open-source GraphQL ecosystem. Many of the tools we've built have become the default in many GraphQL development workflows, such as the [GraphQL Playground](https://github.com/prisma/graphql-playground), [`graphql-yoga`](https://github.com/prisma/graphql-yoga) and [GraphQL Nexus](https://github.com/prisma/nexus) (built by [Tim Griesser](https://twitter.com/tgriesser)). The [recently announced](https://www.prisma.io/blog/using-graphql-nexus-with-a-database-pmyl3660ncst) `nexus-prisma` makes it incredibly easy to implement a GraphQL server on top of Prisma. With the upcoming [Yoga2](https://www.youtube.com/watch?v=3eoxXwllmpk) framework, we further aim to create a Ruby-on-Rails developer experience for GraphQL. ### Contributing to the GraphQL community Similar to how we invest into the GraphQL ecosystem, we want to contribute to the GraphQL community. We're running the world's largest [GraphQL community conference](https://graphqlconf.org) and maintain popular resources like [How to GraphQL](https://howtographql.com) and [GraphQL Weekly](https://www.graphqlweekly.com). > While we weren't among the first companies to join, we're certainly also planning to become part of the [**GraphQL Foundation**](https://gql.foundation/) and help steer the future direction of it. --- ## 🔮 A glimpse into the future As highlighted throughout this post, we are working on many exciting and fundamental improvements to Prisma. To get an overview of what we are working on, feel free to check out our [roadmap](https://pris.ly/roadmap). We are speccing all upcoming features in public (via GitHub issues and an [RFC](https://github.com/prisma/specs) process), so please join the discussion on [GitHub](https://github.com/prisma) and share your opinions with us! **If you have any questions or comments, [please share them on Spectrum](https://spectrum.chat/prisma/general/how-prisma-and-graphql-fit-together~8c05c8f2-84c7-4ced-8f16-74d9798c71fa).** > [**We are hiring!**](https://www.prisma.io/careers) As you will find, one item on the roadmap is a full rewrite of the Prisma core in Rust. If you are a Rust engineer or just generally interested in highly technical challenges and open-source development, definitely check out our [jobs page](https://www.prisma.io/careers). --- ## [Prisma Client (Preview): Simplified & Type-safe Database Access](/blog/prisma-client-preview-ahph4o1umail) **Meta Description:** No description available. **Content:** > ⚠️ **This article is outdated** as it relates to [Prisma 1](https://github.com/prisma/prisma1) which is now [deprecated](https://github.com/prisma/prisma1/issues/5208). To learn more about the most recent version of Prisma, read the [documentation](https://www.prisma.io/docs). ⚠️ ## Prisma client: The next evolution of Prisma bindings Prisma turns your database into a GraphQL API. This GraphQL API is usually not consumed directly by frontend applications, but is used as a _database abstraction_ to simplify data access in application servers (similar to an ORM). When implementing a GraphQL server with Prisma, the resolvers of your GraphQL servers connect to the Prisma API using [Prisma bindings](https://github.com/prisma/prisma1/tree/master/docs/1.14) and [schema delegation](https://www.prisma.io/blog/graphql-schema-stitching-explained-schema-delegation-4c6caf468405). > **Schema delegation** is an advanced way to implement resolvers by forwarding incoming requests (using the [`info`](https://www.prisma.io/blog/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a) object) to another GraphQL API. While schema delegation is a powerful and elegant concept, it is best suited for advanced use cases. Striving to make Prisma more flexible and easier to use, we are introducing a new way to consume Prisma's API in your application: **The Prisma client**.
![Evolution of Prisma bindings](https://i.imgur.com/OyIQQxF.png)
### More use cases: Build GraphQL servers, REST APIs & more The new Prisma client serves a similar purpose as Prisma bindings with three major differences: - While Prisma bindings are designed for GraphQL servers, Prisma client is **more flexible and can be used for more use cases such as REST APIs, CLIs, scripting, etc.** - Prisma client is an integral part of the Prisma toolchain: It is **configured in `prisma.yml` and generated with the Prisma CLI**. - Prisma client is **available in various languages**. Today's preview release makes it available in JavaScript, TypeScript, Flow and Go! ### Can I still use Prisma bindings for my GraphQL server? Prisma bindings remain a powerful way to implement GraphQL resolvers by delegating to the underlying Prisma API. If Prisma bindings work well for your current use case, there is no need to change your implementation to use the new Prisma client. --- ## Generating the Prisma client Prisma client is a library that connects to your Prisma API. It is auto-generated based on your Prisma datamodel and thus aware of all API operations and data structures. To generate a Prisma client, you need to do two things: 1. Specify the new `generate` property in your `prisma.yml`, e.g.: ```yml generate: - generator: typescript-client output: ./prisma-client/ ``` 2. Run the new `prisma generate` command in the Prisma CLI. It reads information from `prisma.yml` and your datamodel to generate the Prisma client. **Note that this only works with Prisma 1.17-beta or higher.** The code above demonstrates how to generate the client in TypeScript; for JavaScript, Flow and Go you can use the following values for `generator`: `javascript-client`, `flow-client` and `go-client`. ## Using the Prisma client API The Prisma client API is generated based on your datamodel and exposes CRUD operations for each model. All following code examples are based on the datamodel below: ```graphql type Post { id: ID! @unique title: String! author: User! } type User { id: ID! @unique email: String! @unique name: String! posts: [Post!]! } ``` > You can check out the full documentation for the new Prisma client API [here](https://v1.prisma.io/docs/1.34/prisma-client/). ### Importing the Prisma client instance Once generated, you can import the Prisma client instance into your code: ```js const { prisma } = require('./prisma-client') ``` ```ts const { prisma } = require('./prisma-client') ``` ```go import "github.com/you/repo/prisma-client" client := prisma.New(nil) ``` ### Reading data While Prisma bindings expose all queries via the `query` field, queries can be invoked directly on the generated Prisma client: ```js const allUsers = await prisma.users() ``` ```ts const allUsers: User[] = await prisma.users() ``` ```go users := client.Users(nil).Exec() ``` This returns all _scalar_ fields of the returned `User` objects. Relations can be queried elegantly using method chaining (also referred to as a [fluent API](https://www.sitepoint.com/javascript-like-boss-understanding-fluent-apis/)): ```js const postsByUser = await prisma.user({ email: 'alice@prisma.io' }).posts() ``` ```ts const postsByUser: Post[] = await prisma.user({ email: 'alice@prisma.io' }).posts() ``` ```go email := "alice@prisma.io" postsByUser := client. User(&prisma.UserWhereUniqueInput{Email: &email}). Posts(nil). Exec() ``` Note that the snippet above still results in a single request to the Prisma API which is then resolved against the database by Prisma's powerful query engine. It is also still possible to use GraphQL to query nested data or use schema delegation for advanced use cases with the new Prisma client API. > See more examples in the [documentation](https://v1.prisma.io/docs/1.34/prisma-client/basic-data-access/reading-data-JAVASCRIPT-rsc2/). ### Writing data Just like queries, mutations are also exposed on the top-level on your Prisma client: ```js const newUser = await prisma.createUser({ name: 'Alice', email: 'alice@prisma.io', }) ``` ```ts const newUser: User = await prisma.createUser({ name: 'Alice', email: 'alice@prisma.io', }) ``` ```go client.CreateUser(&prisma.UserCreateInput{ Name: "Alice", Email: "alice@prisma.io", }) ``` You can also perform several write operations in a single transaction: ```js const newUserWithPosts = await prisma.createUser({ name: 'Bob', email: 'bob@prisma.io', posts: { create: [ { title: 'Hello World', }, { title: 'I ❤️ Prisma', }, ], }, }) ``` ```ts const newUserWithPosts: User = await prisma.createUser({ name: 'Bob', email: 'bob@prisma.io', posts: { create: [ { title: 'Hello World', }, { title: 'I ❤️ Prisma', }, ], }, }) ``` ```go client.CreateUser(&prisma.UserCreateInput{ Name: "Bob", Email: "bob@prisma.io", Posts: &prisma.PostCreateManyWithoutAuthorInput{ Create: &prisma.PostCreateWithoutAuthorInput{ Title: "Hello World", }, }, }) ``` > See more examples in the [documentation](https://v1.prisma.io/docs/1.34/prisma-client/basic-data-access/writing-data-JAVASCRIPT-rsc6/). ### No boilerplate: Type-safety through code generation One core benefit of the Prisma client is [type-safety](https://en.wikipedia.org/wiki/Type_safety). Type-safety fosters productivity, better maintainability, easier refactoring and makes for a great developer experience. Type-safe data access requires a lot of manual work, writing boilerplate code and redundant type definitions. The Prisma client leverages code generation in order to provide custom typings for data models and queries. --- ## Try out Prisma client To learn more about the Prisma client, check out the new [examples](https://github.com/prisma/prisma-examples) repository or follow the "Get Started" tutorial. Please let us know what you think on [Slack](https://slack.prisma.io) 🙌

--- ## [How Prisma Helps Rapha Manage Their Mobile Application Data](/blog/helping-rapha-access-data-across-platforms-n3jfhtyu6rgn) **Meta Description:** No description available. **Content:** ## Summary Prisma helps Rapha deliver a consistent user experience across web, mobile, and physical store locations by making it easy to access user data: * Prisma simplifies access to their PostgreSQL data for both their Android and iOS applications * Prisma Migrate manages and applies schema changes in their development and production environments * Prisma helps Rapha stay flexible, allowing them to evaluate data storage options while maintaining a consistent developer experience Rapha is a company dedicated to redefining comfort, performance, and style for cyclists around the world, whether beginners or World Tour professionals. Cyclists love their products and their commitment to the community and the sport. In addition to being an activewear brand, Rapha is a resource within the cycling community. They regularly organize and sponsor unique rides and events and founded the Rapha Cycling Club in 2015 to bring cyclists together. The Rapha Foundation, meanwhile, is dedicated to funding non-profit organizations to help build a better future for the sport by supporting the next generation of racers. ## Rapha's Platforms and Data Infrastructure Rapha's involvement with its community provides many unique opportunities and challenges. Offering products and services both online and in Rapha Clubhouses throughout the world helps them connect with users where ever they happen to be. These user touchpoints include Android and iOS applications, an e-commerce website, and a variety of web content like blog posts. A side effect of interfacing with users in so many unique mediums is that a variety of systems are involved in managing user data. Their data infrastructure reflects this. ![Rapha's data architecture](/blog/posts/rapha_architecture_diagram.png) Rapha's web team addresses its data requirements primarily with: * SAP Hybris and Commerce Cloud: manages their e-commerce website data including user information related to purchases Meanwhile, Rapha's mobile team uses a stack that includes: * PostgreSQL: their main database hosted on Amazon RDS * Prisma 2: next-generation ORM for Node.js and TypeScript * Nexus Schema: TypeScript and JavaScript type definitions to generate GraphQL APIs * Apollo Server: a GraphQL server to serve the generated API * [Contentful](https://www.contentful.com/): an API-driven content management solution the team uses to handle blog posts and other content Rapha uses Prisma to develop and manage the data API that their mobile applications rely on. The majority of the team's data is stored in a PostgreSQL database running on Amazon RDS. Rather than interfacing with the database directly, they use Prisma to build and manage schemas that serve as the basis of their data API. They can then use Apollo server to serve the API to their mobile applications. The services above are all packaged into [Docker containers](https://www.docker.com/resources/what-container) and deployed to Amazon's Elastic Container Service. Long-running and asynchronous tasks are added to Amazon's SQS message queuing service and consumed by Amazon Lambda functions. Rapha relies on [Cloudflare](https://www.cloudflare.com/) at the edge to accelerate access for users around the world. ## What Rapha Needed From Its Data Layer Rapha wanted tooling to help their mobile team develop against their database quickly and safely. As a small team supporting both iOS and Android applications, they wanted to make it easy to develop and deploy schema changes in an organized manner. This meant synchronizing changes between the backing database and the GraphQL API that their mobile applications interface with. In addition to this, they wanted more control and flexibility to make changes down the road as their requirements evolve. Whether moving to new technologies by choice or necessity, Rapha wanted to be able to maintain a stable interface to their data regardless of what was responsible for managing and serving it. Rapha evaluated Prisma as a way to build a data API to address both of these concerns. ## How Prisma Helps Abstract Rapha's Data Infrastructure Rapha's mobile team uses Prisma to help them develop its GraphQL API for their PostgreSQL data. This API is then served by Apollo server and consumed by both their iOS and Android applications. With Prisma, the team can modify their data structures by making changes to the [Prisma schema](https://www.prisma.io/docs/concepts/components/prisma-schema) file. The schema file serves as a single source of truth for the structure of their data models. It is used to update the tables in the underlying database and allows the team to easily build changes into the API. By combining Prisma with their GraphQL API, Rapha is able to abstract the data source and make it easily accessible to each platform. Prisma is responsible for managing changes between the API layer and the database. Meanwhile, the GraphQL API created from the Prisma schema provides a unified interface for their applications. Prisma's type-safety helps make updates to the API easier and safer to implement. Together, they allow the team to evolve their data models to respond to changing requirements. ## Managing Migrations As Rapha's mobile applications evolve, changes to the database schema must be managed carefully to ensure that the API and application versions remain compatible. Prisma provides tooling to safely deploy changes to their development and production environments. Since Prisma defines its data structures for applications and databases in a schema file, changes to the data model are centralized. [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate) can be used to detect changes to the schema file and generate SQL migration files. These can be stored in version control and run against databases to transform their data structures. When it is time to deploy the schema change, the team can use Prisma Migrate to apply the changes to the database automatically as part of their CI/CD pipeline or they can run the generated SQL script against the database manually. ## Building for the Future Prisma's abstraction over Rapha's PostgreSQL database helps them prepare for a time when they might have additional data sources. While their Prisma configuration currently only manages the schema of a single database, it acts as a framework for additional changes. Over the next few years, Rapha foresees their data API growing as they offer new services and integrate experiences across their platforms. Prisma will allow them to choose the databases that fit the needs of each service while minimizing the impact on their developer experience. This is relevant when choosing the databases for their new services and when reevaluating whether the databases they currently rely on are still the best choice. ## Conclusion Rapha's mobile and web platforms continue to grow with new services, products, and events always on the horizon. The development team is able to provide users of their e-commerce platform, mobile apps, and physical Rapha Clubhouses a unified, personal experience. --- ## [Key takeaways from the Discover Data DX virtual event](/blog/datadx-event-recap-z5Pcp6HzBz5m) **Meta Description:** Highlights from the Discover Data DX virtual event hosted by Prisma on December 7th, 2023, where industry leaders discussed the significance and principles of Data DX. **Content:** Software development is now accessible to a wider audience, yet the data complexity when building applications has grown. These shifts highlight the need for simpler and more intuitive tools that empower developers to focus on the applications they want to build. The new [Data DX](https://www.datadx.io/) category embodies this vision to simplify data-driven application development without sacrificing depth or functionality. ### Bringing the industry together Prisma's Discover Data DX event showcased the role of Data DX as a unifying concept. It was inspiring to see varied companies embrace Data DX's principles. Together, they explored its meaning and how collaborative efforts could enhance the developer experience significantly.
The strength of the ecosystem is a core component of Data DX. It is an essential consideration for developers when evaluating new tooling.
## The evolution of database technologies The first panel delved into how the developer experience with databases has evolved. Panelists from Prisma, Xata, PlanetScale, Snaplet, and Turso shared unique insights on enhancing the developer experience with databases. A central topic was distinguishing between necessary and accidental complexities in database management. The goal? **Simplify for developers** while recognizing some complexities are unavoidable. The panel also examined how to **balance powerful database capabilities and developer experience**. They believe it is crucial to deliver ease of use without compromising the advanced features developers require.
I just want to fix bugs, build features, and ship. I don't want to have to deal with the complexity of getting access to data.
The discussion also covered emerging challenges in database management, such as schema changes, serverless technology, and AI/ML integration.
**Panelists** - [Deepthi Sigireddi](https://twitter.com/ATechGirl), Engineering Lead for Vitess at **PlanetScale** - [Glauber Costa](https://twitter.com/glcst), Founder/CEO at **Turso** - [Peter Pistorius](https://twitter.com/appfactory), Founder at **Snaplet** - [Tudor Golubenco](https://twitter.com/tudor_g), CTO at **Xata** - [Søren Bramer Schmidt](https://twitter.com/sorenbs), CEO at **Prisma** Moderated by [Petra Donka](https://twitter.com/petradonka), Head of Developer Connections at **Prisma** ## The future of building data-driven apps The second segment focused on the evolution of developer experience in data-driven application development, with representatives from Grafbase, Tinybird, RedwoodJS and Prisma sharing diverse perspectives. ### The crucial role of developer experience High-quality developer experience is fundamental to the future of application development. The panel specifically discussed reducing repetitive tasks, automating workflows, and integrating tools and platforms effectively. The consensus was that modern tools should significantly **reduce time to market**, enabling developers to concentrate on product development rather than infrastructure.
Why does the front-end community get such excellent tooling while back-end developers struggle with outdated systems and tools?
The discussion highlighted the gap in tooling quality between front-end and back-end development, especially in data management. Beyond pure scalability, the industry is now shifting to prioritize ease of use and developer experience in back-end and data tools. The panel also touched on AI's potential in application development, with Tinybird experimenting in this area, noting the need for human oversight.
**Panelists** - [Fredrik Björk](https://twitter.com/fbjork), CEO at **Grafbase** - [Amy Dutton](https://twitter.com/selfteachme), Lead maintainer at **RedwoodJS** - [Alasdair Brown](https://github.com/sdairs), Head of DevRel at **Tinybird** - [Søren Bramer Schmidt](https://twitter.com/sorenbs), CEO at **Prisma** Moderated by [Petra Donka](https://twitter.com/petradonka), Head of Developer Connections at **Prisma** ## Shaping the future The Discover Data DX event was essential in establishing Data DX as an emerging category. It highlighted the industry alignment on the need for a more intuitive, efficient, and developer-focused approach to application development. Prisma will spearhead more initiatives to grow Data DX, driving innovation and collaboration in the industry. Learn more and stay updated at [datadx.io](https://www.datadx.io). --- ## [Prisma Client Extensions Are Now Production Ready](/blog/client-extensions-ga-4g4yIu8eOSbB) **Meta Description:** Make Prisma Client do even more with Client extensions, now Generally Available. Extend your client, models, queries, and results to tailor Prisma Client to your use case. **Content:** ## Tailor Prisma Client to meet your codebase's needs In [4.7.0](https://github.com/prisma/prisma/releases/tag/4.7.0), we released Prisma Client extensions [as a Preview feature](https://www.prisma.io/docs/orm/more/releases#preview). Today we are happy to announce the General Availability of Prisma Client extensions! Extensions have proven to be extremely useful and powerful during the Preview period, even powering Prisma products like [Accelerate](https://www.prisma.io/data-platform/accelerate) and [Optimize](https://www.prisma.io/docs/optimize)! ### A straightforward and easy to use API If this is the first time you're hearing about Client extensions, don't worry. We have [an existing blog post](/client-extensions-preview-8t3w27xkrxxn) that covers the usage in-depth. To sum it up here: creating an extension is as easy as using `$extends`. This code snippet shows how you can add a _new method_ to the `User` model using a [`model`](https://www.prisma.io/docs/orm/prisma-client/client-extensions/model) extension: ```typescript import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient().$extends({ model: { user: { async signUp(email: string) { // code for the new method goes inside the brackets }, }, }, }); // The new method can then be used like this: const newUser = await prisma.user.signUp('myemail@email.com'); ``` If you instead require a method on _all models_, you can even use the builtin `$allModels` feature: ```typescript import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient().$extends({ model: { $allModels: { async exists( this: T, where: Prisma.Args['where'] ): Promise { // code for the new method goes inside the brackets }, }, }, }); // You can now invoke `exists` on any of your models. For example: const postExists = await prisma.post.exists({ id: 1 }); ``` For a more in-depth look into changes we made to the extensions API as a part of this release, please check out [our release notes](https://github.com/prisma/prisma/releases/tag/4.16.0) ### Extensions built by the community While client extensions are now generally available, we have already seen some cool examples in the wild. [`prisma-extension-pagination`](https://github.com/deptyped/prisma-extension-pagination) is an awesome contribution from our community. Importing and using an external client extension is easy too: ```typescript import { PrismaClient } from '@prisma/client'; import pagination from 'prisma-extension-pagination'; const prisma = new PrismaClient().$extends(pagination); const [users, meta] = prisma.user .paginate({ select: { id: true, } }) .withPages({ limit: 10, }); ``` ### Reference examples for various use cases In addition to community contributions, we have a set of reference examples in the [`prisma-client-extensions` example repository](https://github.com/prisma/prisma-client-extensions) that showcase different areas where we believe Prisma Client extensions can be useful. The repository currently contains the following example extensions: | Example | Description | | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | [audit-log-context](https://github.com/prisma/prisma-client-extensions/tree/main/audit-log-context) | Provides the current user's ID as context to Postgres audit log triggers | | [callback-free-itx](https://github.com/prisma/prisma-client-extensions/tree/main/callback-free-itx) | Adds a method to start interactive transactions without callbacks | | [computed-fields](https://github.com/prisma/prisma-client-extensions/tree/main/computed-fields) | Adds virtual / computed fields to result objects | | [input-transformation](https://github.com/prisma/prisma-client-extensions/tree/main/input-transformation) | Transforms the input arguments passed to Prisma Client queries to filter the result set | | [input-validation](https://github.com/prisma/prisma-client-extensions/tree/main/input-validation) | Runs custom validation logic on input arguments passed to mutation methods | | [instance-methods](https://github.com/prisma/prisma-client-extensions/tree/main/instance-methods) | Adds Active Record-like methods like `save()` and `delete()` to result objects | | [json-field-types](https://github.com/prisma/prisma-client-extensions/tree/main/json-field-types) | Uses strongly-typed runtime parsing for data stored in JSON columns | | [model-filters](https://github.com/prisma/prisma-client-extensions/tree/main/model-filters) | Adds reusable filters that can composed into complex where conditions for a model | | [obfuscated-fields](https://github.com/prisma/prisma-client-extensions/tree/main/obfuscated-fields) | Prevents sensitive data (e.g. password fields) from being included in results | | [query-logging](https://github.com/prisma/prisma-client-extensions/tree/main/query-logging) | Wraps Prisma Client queries with simple query timing and logging | | [readonly-client](https://github.com/prisma/prisma-client-extensions/tree/main/readonly-client) | Creates a client that only allows read operations | | [retry-transactions](https://github.com/prisma/prisma-client-extensions/tree/main/retry-transactions) | Adds a retry mechanism to transactions with exponential backoff and jitter | | [row-level-security](https://github.com/prisma/prisma-client-extensions/tree/main/row-level-security) | Uses Postgres row-level security policies to isolate data a multi-tenant application | | [static-methods](https://github.com/prisma/prisma-client-extensions/tree/main/static-methods) | Adds custom query methods to Prisma Client models | | [transformed-fields](https://github.com/prisma/prisma-client-extensions/tree/main/transformed-fields) | Demonstrates how to use result extensions to transform query results and add i18n to an app | | [exists-fn](https://github.com/prisma/prisma-client-extensions/tree/main/exists-fn) | Demonstrates how to add an exists method to all your models | ### Show off your extensions! If you'd like a deeper dive into Prisma Client extensions, be sure to check out our previous write-up: [Prisma Client Just Became a Lot More Flexible: Prisma Client Extensions](/client-extensions-preview-8t3w27xkrxxn)! We'd also love to hear about your extensions (and maybe even take them for a spin). Be sure to show of your `#MadeWithPrisma` work in our [Discord](https://discord.gg/KQyTW2H5ca) --- ## [Prisma 2.0 is in Beta: Type-safe Database Access with Prisma Client](/blog/prisma-2-beta-b7bcl0gd8d8e) **Meta Description:** No description available. **Content:** ## Contents - [Modern database access with Prisma Client 2.0](#modern-database-access-with-prisma-client-20) - [What's in this release?](#whats-in-this-release) - [Renaming the `prisma2` repository to `prisma`](#renaming-the-prisma2-repository-to-prisma) - [Renaming the `prisma2` CLI](#renaming-the-prisma2-cli) - [I currently use Prisma 1; what should I do?](#i-currently-use-prisma-1-what-should-i-do) - [Try out Prisma 2.0 and share your feedback](#try-out-prisma-20-and-share-your-feedback) --- ## TL;DR - The Prisma 2.0 **Beta** is ready. With the new website and documentation, it's now the default for new developers getting started with Prisma. - Prisma 2.0 mainly consists of Prisma Client, an auto-generated and type-safe query builder for Node.js and TypeScript. Prisma Migrate is considered _experimental_. - The `prisma/prisma2` repo has been renamed to `prisma/prisma` (and the former Prisma 1 repo `prisma/prisma` repo is now called `prisma/prisma1`). Try the new Prisma Client in 5 minutes by following the [**Quickstart**](https://www.prisma.io/docs/getting-started/quickstart) in the new docs. --- ## Modern database access with Prisma Client 2.0 The new version of Prisma Client is a modern database access library for Node.js and TypeScript. It can be used as an alternative to traditional ORMs and SQL query builders to read and write data in your database. To set it up, you need a [Prisma schema file](https://www.prisma.io/docs/concepts/components/prisma-schema) and must add Prisma Client as a dependency to your project: ``` npm install @prisma/client ``` Prisma Client can be used in _any_ Node.js or TypeScript backend application (including serverless applications and microservices). This can be a [REST API](https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/rest), a [GraphQL API](https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/graphql), a gRPC API, or anything else that needs a database. ### Be more productive with your database The main goal of Prisma Client is to increase the productivity of application developers when working with databases. It achieves this by providing a clean data access API that returns plain JavaScript objects. This approach enables simpler reasoning about database queries and increases the confidence with predictable (and type-safe) query results. Here are a couple of the major benefits Prisma Client provides: - **Auto-completion** in code editors instead of needing to look up documentation - **Thinking in objects** instead of mapping relational data - **Type-safe database queries** that can be validated at compile time - **Single source of truth** for database and application models - **Healthy constraints** that prevent common pitfalls and antipatterns - **An abstraction that makes the right thing easy** ("pit of success") - **Queries not classes** to avoid complex model objects - **Less boilerplate** so developers can focus on the important parts of their app Learn more about how Prisma makes developers productive in the [Introduction](https://www.prisma.io/docs/concepts/overview/what-is-prisma) or get a taste of the Prisma Client API by checking out the code examples on the [website](https://www.prisma.io/). ### A "smart" node module 🤓 The `@prisma/client` module is different from "conventional" node modules. With conventional node modules (e.g., [`lodash`](https://lodash.com/)), the entire package is downloaded into your `node_modules` directory and only gets updated when you re-install the package. The `@prisma/client` node module is different. It is a ["facade package"](https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/generating-prisma-client##the-prismaclient-npm-package) (basically a _stub_) that doesn't contain any functional code. While you do need to install it _once_ with `npm install @prisma/client`, it is likely that the code inside the `node_modules/@prisma/client` directory changes more often as you're evolving your application. That's because whenever you make changes to the Prisma schema, you need to re-generate Prisma Client, which updates the code in the `@prisma/client` node module. Because the `node_modules/@prisma/client` directory contains some code that is _tailored to your_ project, it is sometimes called a "smart node module": ![Prisma smart node module](https://i.imgur.com/83djlkl.png) ### Auto-completion and type-safety benefits even in plain JavaScript Auto-completion is an extremely powerful tool for developers. It allows them to explore an API directly in their editor instead of referring to documentation. Prisma Client brings auto-completion to your database queries! Thanks to Prisma Client's generated types, which are included in the `index.d.ts` of the `@prisma/client` module, this feature is available not only to TypeScript developers, but also when developing an application in plain JavaScript. ### Type-safety for partial database queries A major benefit of Prisma Client compared to other ORMs and database tools is that it provides _full type safety_ - even for "partial" database queries (i.e., when you query only the subset of a model's field or include a [relation](https://www.prisma.io/docs/concepts/components/prisma-schema/relations)). As an example, consider this Prisma Client query (you can switch the tab to view the corresponding [Prisma models](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model)): ```ts const usersWithPartialPosts = await prisma.user.findMany({ include: { posts: { select: { title: true, published: true, }, }, }, }) ``` ```prisma model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) author User? } model User { id Int @id @default(autoincrement()) email String @unique name String? posts Post[] } ``` Note that the resulting `usersWithPartialPosts` will be _statically typed_ to: ```ts export type User = { id: number email: string name: string | null } const usersWithPartialPosts: (User & { posts: { title: string published: boolean }[] })[] ``` This means that TypeScript will catch any errors when you make a typo or accidentally access a property that was not requested from the database! ### Getting started The best way to get started with Prisma Client is by following the [**Quickstart**](https://www.prisma.io/docs/getting-started/quickstart) in the docs:
Alternatively, you can: - [Set up a new project with Prisma from scratch](https://www.prisma.io/docs/getting-started/setup-prisma) - [Add Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project/relational-databases-typescript-postgresql) ## What's in this release? The Prisma 2.0 Beta comes with the following tools: - **Prisma Client**: Auto-generated, type-safe query builder for Node.js & TypeScript - **Prisma Migrate** (_experimental_): Declarative schema migration tool - **Prisma Studio** (_experimental_): GUI to view and edit data in your database Try the new Prisma Client in 5 minutes by following the [**Quickstart**](https://www.prisma.io/docs/getting-started/quickstart) in the new docs. > **Note**: Learn more about the Beta release in the [release notes](https://github.com/prisma/prisma/releases/tag/2.0.0-beta.1). ## Renaming the `prisma2` repository to `prisma` Since its initial release, the main repository for Prisma 2.0 has been called `prisma2`. Because Prisma 2.0 is now the default for developers getting started with Prisma, the Prisma repositories have been renamed as follows: - The `prisma/prisma2` repository has been renamed to [`prisma/prisma`](https://github.com/prisma/prisma/) - The `prisma/prisma` repository has been renamed to [`prisma/prisma1`](https://github.com/prisma/prisma1/) ## Renaming the `prisma2` CLI During the Preview period, the CLI for Prisma 2.0 was invoked using the `prisma2` command. With Prisma 2.0 being the default for new developers getting started with Prisma, the command is changed to just `prisma`. The exist ing `prisma` command of Prisma 1 is renamed to `prisma1`. Also, note that the installation of the npm packages changes: | Prisma version | Old CLI command | New CLI command | Old npm package name | New npm package name | | :------------- | :-------------- | :-------------- | :------------------- | :------------------- | | 2.0 | `prisma2` | `prisma` | `prisma2` | `@prisma/cli` | | 1.X | `prisma` | `prisma1` | `prisma` | `prisma1` | ### A note for current Prisma 1 users If you're currently using Prisma 1 with the `prisma` command, you can keep using it as before. **If you want to upgrade to Prisma 2.0**, it is recommended to uninstall your current `prisma` installation and install the new CLI versions locally in the projects where they are needed: ``` # Remove global installation npm uninstall -g prisma # Navigate into Prisma 1 project directory & install locally cd path/to/prisma-1-project npm install prisma1 --save-dev # Invoke `prisma1` by prefixing it with `npx` npx prisma1 ``` ### The `prisma2` npm package is deprecated The `prisma2` npm package is now deprecated. To prevent confusions during installation, it now outputs the following when you try to install it: ``` ┌─────────────────────────────────────────────────────────────┐ │ │ │ The package prisma2 has been renamed to @prisma/cli. │ │ │ │ Please uninstall prisma2 from your project or globally. │ │ Then install @prisma/cli to continue using Prisma 2.0: │ │ │ │ # Uninstall old CLI │ │ npm uninstall prisma2 │ │ │ │ # Install new CLI │ │ npm install @prisma/cli --save-dev │ │ │ │ # Invoke via npx │ │ npx prisma2 --help │ │ │ │ Learn more here: https://pris.ly/preview025 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## I currently use Prisma 1; what should I do? First of all, we want to hugely thank all existing Prisma 1 users! 🙏 We are deeply grateful for a supportive and active community that has formed on GitHub and [Slack](https://slack.prisma.io)! ### How does Prisma 2.0 compare to Prisma 1? Prisma 2.0 comes with a number of changes compared to Prisma 1. Here's a high-level overview of the **main differences**: - Prisma 2.0 doesn't require hosting a database proxy server (i.e., the [Prisma server](https://v1.prisma.io/docs/1.34/prisma-server)). - Prisma 2.0 doesn't expose ["a GraphQL API for your database"](https://www.prisma.io/blog/prisma-and-graphql-mfl5y2r7t49c) anymore, but only allows for _programmatic access_ via the Prisma Client API. - Prisma 2.0 makes the features of Prisma 1 more modular and splits them into dedicated tools: - Prisma Client: An improved version of Prisma client 1.0 - Prisma Migrate: Data modeling and migrations (formerly `prisma deploy`). - More powerful introspection allows connecting Prisma 2.0 to any existing database. - Prisma 1 datamodel and `prisma.yml` have been merged into the [Prisma schema](https://www.prisma.io/docs/concepts/components/prisma-schema). - Prisma 2.0 uses its own [modeling language](https://github.com/prisma/specs/tree/master/schema) instead of being based on GraphQL SDL. - You can build GraphQL servers with Prisma using [Nexus](https://nexusjs.org/) or any other [GraphQL library](https://www.prisma.io/docs/concepts/overview/prisma-in-your-stack/graphql) of your choice. ### How can I access the Prisma 1 docs? You can keep accessing specific versions of the Prisma 1 docs by appending the version number to `https://www.prisma.io/docs`. For example, to view the docs for Prisma version 1.34, you can go to [`https://v1.prisma.io/docs/1.34/`](https://v1.prisma.io/docs/1.34/). The Prisma 1 examples have been moved to the [`prisma1-examples`](https://github.com/prisma/prisma1-examples/) repository. ### Should I upgrade? Whether or not you should upgrade depends on the context of your project. In general, one major consideration is the fact that Prisma Migrate is still experimental. This means you probably need to make any future adjustments to your database schema using SQL or another migration tool. Also, note that we will put together an [upgrade guide as well as dedicated tooling](https://github.com/prisma/prisma/issues/1937) for the upgrade process over the next weeks. So, if you do want to upgrade despite Prisma Migrate not being ready, it might be worth waiting until these resources are in place. #### I use Prisma 1 with Prisma client and `nexus-prisma`, should I upgrade? It is certainly possible to upgrade a project that's running on Prisma 1 and `nexus-prisma` to Prisma 2.0. If you decide to upgrade, be aware that changing your database schema after having upgraded to Prisma 2.0, will require running migrations with SQL or a third-party migration tool. Also, note that the `nexus-prisma` API changes with Prisma 2.0. Here is a high-level overview of the steps needed to upgrade: 1. Install the Prisma 2.0 CLI in your project: `npm install @prisma/cli --save-dev` 1. Create a Prisma schema with a `datasource` that points to your Prisma 1 database 1. Introspect your Prisma 1 database to get your datamodel: `npx prisma introspect` 1. Install the Prisma Client npm package: `npm install @prisma/client` 1. Generate Prisma Client JS: `npx prisma generate` 1. Upgrade to the latest version of `nexus-prisma` and adjust your resolvers. > **Note**: You can find your database credentials in the Docker Compose file that you used to deploy the Prisma server. These credentials are needed to compose the [connection URL](https://www.prisma.io/docs/reference/database-reference/connection-urls) for Prisma 2.0. #### I use Prisma 1 with Prisma client (without `nexus-prisma`), should I upgrade? It is certainly possible to upgrade a project that's running on Prisma 1. If you decide to upgrade, be aware that changing your database schema after having upgraded to Prisma 2.0 will require running migrations with SQL or a third-party migration tool. Here is a high-level overview of the steps needed to upgrade: 1. Navigate into your project directory 1. Install the Prisma 2.0 CLI in your project: `npm install @prisma/cli --save-dev` 1. Create a Prisma schema with a `datasource` that points to your Prisma 1 database 1. Introspect your Prisma 1 database to get your datamodel: `npx prisma introspect` 1. Install the Prisma Client npm package: `npm install @prisma/client` 1. Generate Prisma Client JS: `npx prisma generate` 1. Update your previous uses of Prisma client 1.0 to the new Prisma Client 2.0 > **Note**: You can find your database credentials in the Docker Compose file that you used to deploy the Prisma server. These credentials are needed to compose the [connection URL](https://www.prisma.io/docs/reference/database-reference/connection-urls) for Prisma 2.0. #### I use Prisma 1 with `prisma-binding`, should I upgrade? It is certainly possible to upgrade a project that's running on Prisma 1 and `prisma-binding` to Prisma 2.0. If you decide to upgrade, be aware that changing your database schema after having upgraded to Prisma 2.0 will require running migrations with SQL or a third-party migration tool. Also, note that the way how your GraphQL resolvers are implemented changes with Prisma 2.0. As Prisma 2.0 doesn't expose a GraphQL API for your database, you can't use the `prisma-binding` npm package anymore. This is mostly relevant for implementing _relations_, resolvers for these now need to be implemented on a _type level_. To learn more about why this is necessary, be sure to read this article about the basics of [GraphQL schemas](https://www.prisma.io/blog/graphql-server-basics-the-schema-ac5e2950214e). Here is a high-level overview of the steps needed to upgrade: 1. Install the Prisma 2.0 CLI in your project: `npm install @prisma/cli --save-dev` 1. Create a Prisma schema with a `datasource` that points to your Prisma 1 database 1. Introspect your Prisma 1 database to get your datamodel: `npx prisma introspect` 1. Install the Prisma Client npm package: `npm install @prisma/client` 1. Generate Prisma Client JS: `npx prisma generate` 1. Adjust your resolvers to use Prisma Client instead of `prisma-binding` If you want to switch to a [code-first](https://www.prisma.io/blog/the-problems-of-schema-first-graphql-development-x1mn4cb0tyl3) approach, check out [GraphQL Nexus](https://nexusjs.org/). > **Note**: You can find your database credentials in the Docker Compose file that you used to deploy the Prisma server. These credentials are needed to compose the [connection URL](https://www.prisma.io/docs/reference/database-reference/connection-urls) for Prisma 2.0. ## Try out Prisma 2.0 and share your feedback We are really excited to finally share the Beta version of Prisma 2.0 and can't wait to see what you all build with it.
If you want to leave feedback, share ideas, create feature requests or submit bug reports, please do so in the (renamed) [`prisma`](https://github.com/prisma/prisma) repository on GitHub and join the (renamed) [`#prisma2-beta`](https://app.slack.com/client/T0MQBS8JG/CKQTGR6T0) channel on the [Prisma Slack](https://slack.prisma.io)! --- ## [Accelerate in Preview: Global Database Cache & Scalable Connection Pool](/blog/accelerate-preview-release-ab229e69ed2) **Meta Description:** Accelerate is going into Preview! Learn how to enable high-speed, scalable applications with a global cache and connection pooler. **Content:** ## Table of contents - [Cache query results close to your servers](#cache-query-results-close-to-your-servers) - [Supercharge serverless and edge apps with Accelerate's connection pool](#supercharge-serverless-and-edge-apps-with-accelerates-connection-pool) - [Boost your app performance and scalability](#boost-your-app-performance-and-scalability) - [Let us know what you think](#let-us-know-what-you-think) [Accelerate](https://www.prisma.io/data-platform/accelerate) has transitioned from Early Access to public Preview! Now you can leverage the power of a managed global cache and connection pool with Prisma with support for 300 locations globally and use a connection pool with support for 16 regions. ## Cache query results close to your servers Accelerate ensures that cached query results are always served from the nearest cache node to the application server, resulting in faster response times. Accelerate's cache nodes are built with Cloudflare and are available in 300 locations worldwide. This greatly benefits distributed, serverless, and edge applications as performance remains consistent regardless of the application server's location. This is because a cache node is always available closest to the application server, and when data is cached, large round trips to the database are avoided. Accelerate cache nodes are available globally Suppose a database is located in North America, and a request is made to the database from a server in Japan. By using Accelerate to cache query results, the results can be retrieved from a cache in the same region of Japan, avoiding a round trip of about ~16,000 kilometers (considering the speed of light, there would be an additional latency of approximately 53 milliseconds) to fetch query results from the database in North America. ### Programmatic control over cache behavior Accelerate extends your Prisma Client with an intuitive API offering granular control over established caching patterns on a per-query basis. Utilise [time-to-live](https://www.prisma.io/docs/data-platform/accelerate/concepts#time-to-live-ttl) (TTL) or [state-while-revalidate](https://www.prisma.io/docs/data-platform/accelerate/concepts#stale-while-revalidate-swr) (SWR) to fine-tune your cache behavior tailored to your application needs. ```javascript await prisma.user.findMany({ cacheStrategy: { + ttl: 60, }, }); ``` ```javascript await prisma.user.findMany({ cacheStrategy: { + swr: 30, }, }); ``` ```javascript await prisma.user.findMany({ cacheStrategy: { + ttl: 60, + swr: 30, }, }); ``` > Learn more about caching strategies in our [docs](https://www.prisma.io/docs/data-platform/accelerate/concepts#cache-strategies). To comply with regulations regarding the storage of personally identifiable information (PII) like phone numbers, social security numbers, and credit card numbers, you may need to avoid caching query results. Excluding the `cacheStrategy` from your queries provides a straightforward way to opt out of caching your query results. > To understand the advantages and drawbacks associated with caching database query results, read the blog post Database Caching: A Double-Edged Sword? Examining the Pros and Cons. ## Supercharge serverless and edge apps with Accelerate's connection pool Accelerate seamlessly integrates with serverless and edge environments. While database connections are stateful, serverless and edge environments are stateless, making it challenging to manage stateful connections from a stateless environment. In serverless environments, a sudden surge in traffic can spawn several ephemeral servers (also referred to as ‘serverless functions’) to handle requests. This results in each server opening up one or more database connections, eventually exceeding the database connection limit. > Learn more about the serverless connection management challenge here. Accelerate's built-in connection pool can be deployed in the same region as your database. The connection pool helps you scale your application by persisting and reusing database connections, preventing the connection limit from being exceeded. Accelerate connection pooler ## Boost your app performance and scalability Accelerate caches query results with incredible efficiency, allowing for lightning-fast retrieval of cached data with latencies as low as 5ms. The significant speedup provided by Accelerate is most noticeable when the results of complex, long-running queries are cached. For example, a query that usually takes 30 seconds to process can be cached with Accelerate, resulting in a response time of approximately 5-20 milliseconds, providing a massive ~1000x speedup. | | Queries with Prisma Client | Queries with Prisma Client and Accelerate without caching | Queries with Prisma Client and Accelerate with caching | | :-------------- | :-----------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------: | | **Description** | Prisma Client connects directly to the database and executes the query | The query is routed through the connection pool instance hosted close to the database region | Accelerate caches the query | | **Pros** | • No need to write SQL

• No additional service or component | • Built-in connection pooling for serverless and edge runtimes

• Allows Prisma to be used in Edge Functions

| • Built-in connection pooling for serverless and edge runtimes

• Allows Prisma to be used in Edge Functions

• Performance boost | | **Cons** | • Setting up and managing connection pooling for serverless/edge environments

• Long round-trips in multi-region deployments | • Slight latency overhead due to routing query through Accelerate’s connection pooler | • Data may be stale | Accelerate enables you to serve more users with fewer resources. Storing frequently accessed query results reduces the need for repeated database queries. This improves scalability and performance by freeing up the database to perform more tasks. Application servers can handle more requests if query results are cached because the queries respond faster. This can help accelerate your website's response times.
## Let us know what you think! Get started to supercharge your application with Prisma Accelerate! Try it out and share your experience with us on Twitter or join the conversation on Discord.
    --- ## [Prisma Ambassador Program — Building A Community of Experts](/blog/ambassador-program-nxkWGcGNuvFx) **Meta Description:** We are thrilled to announce the launch of the Ambassador Program to empower the Prisma community, while also helping individual contributors build their own brand. **Content:** ## A huge shoutout to the awesome Prisma community 💚 We're continuosly amazed by the awesome content produced by the [Prisma community](https://www.prisma.io/community), be it in the form of example projects, video tutorials or blog articles! Not to mention how community members support each other in [GitHub Discussions](https://github.com/prisma/prisma/discussions) and on [Stackoverflow](https://stackoverflow.com/questions/tagged/prisma) or have lively discussions and show off their Prisma projects on [Slack](https://slack.prisma.io) (join the [`#showcase`](https://app.slack.com/client/T0MQBS8JG/C565176N6) channel to learn more). --- ## Recognising our community contributors Community contributors have helped us immensely over the years by providing an unvarnished review of their Prisma experience, highlighting the good and the not so good. This has helped shape the experience of new adopters as well as our own product and vision, allowing us to receive genuine and thoughtful feedback (e.g. via the [`#product-feedback`](https://app.slack.com/client/T0MQBS8JG/C01739JGFCM) channel where you can get in touch directly with our Product team). Community contributors are a very powerful force, that influence new and existing users' choices! While Prisma has become significantly more popular over the past year, we're deeply aware that choosing a new tool to work with your database does incur a cognitive and practical cost. To make adoption easier and help our users be more successful with Prisma, we ... - ... provide dedicated community support via [GitHub Discussions](https://github.com/prisma/prisma/discussions) and [Slack](https://slack.prisma.io) - ... incorporate feedback in our roadmap and release new versions [every two weeks](https://github.com/prisma/prisma) - ... invest heavily in education e.g. via extensive [documentation](https://www.prisma.io/docs) and [videos](https://www.youtube.com/prismadata) However, ultimately, **peer to peer feedback is indeed the most influencial approach there is**, and we want to reward those contributors who help spread the word about Prisma. --- ## Introducing the Ambassador Program We wanted to invest in a user-centered, peer-to-peer program, that would grow from the periphery to the center. And so the Prisma Ambassador Program was born! These are the three guiding principles of this program: - **Rewarding and engaging our biggest fans**, who are genuinely passionate about our product, share our values, and enjoy supporting the wider community. - **Build a network of Prisma champions and experts**, creating a space where they can collaborate with one another and share best practices. - **Build long term cooperation with a loyal user base**, to help us shape our product roadmap and ultimately the vision for Prisma. --- ## Why become an Ambassador? A couple of the benefits of becoming a Prisma Ambassador are: - **Networking** with other peers in your field by joining the private Ambassador Slack channel. - **Direct communication** with the Prisma DevRel, Product and Engineering teams. - **Enhancement to your credibility**, as well as strengthening your professional profile. - **Prestige and recognition** for being selected as one of our most outstanding contributors. - Ability to add a **valuable experience** to your resume and media kit. - **Bonuses** in the form of training, swag, trips, design support, etc. --- ## How does it work? Your task as a Prisma Ambassador is to highlight our technologies through the channels and mediums **that best fits your skills**, be that in the form of a blog post, video, event talk, GitHub contributions, etc. We prize quality over quantity. If you're already building valuable Prisma content, we want you to continue to do so, just with more support from our end. Our goal is to make this a mutually beneficial partnership! If you want to become an Ambassador, your mission is to: - Produce at least 1 piece of content per quarter - Answer at least 1 question on [GitHub Discussions](https://github.com/prisma/prisma/discussions) or [Stackoverflow](https://stackoverflow.com/questions/tagged/prisma) per quarter - Attend our quarterly Ambassador Board meetings The more you contribute the more we'll reward you! You can find more information about the program on the new [Ambassador Program website](https://www.prisma.io/ambassador) and the [FAQs](https://pris.ly/ambassador-faq). New Ambassadors will be supported by a dedicated Prisma team throughout the program, providing a tailored onboarding experience and answering all the questions they might have. --- ## We can't wait to read and promote your content Throughtout the years, the Prisma community has been a fantastic source of ideas, feedback and content. We couldn't be more grateful and proud to work for and with such amazing individuals! We hope the [Ambassador Program](https://www.prisma.io/ambassador) will enable you all to further shine and highlight the amazing work you are doing. Don't hesitate to reach out to learn more. We can't wait to see what further content the community will create! --- ## [Build A Fullstack App with Remix, Prisma & MongoDB: Authentication](/blog/fullstack-remix-prisma-mongodb-2-ZTmOy58p4re8) **Meta Description:** Learn how to build and deploy a fullstack application using Remix, Prisma, and MongoDB. In this article, we will be setting up authentication for our Remix application using session-based authentication. **Content:** ## Table Of Contents - [Introduction](#introduction) - [Development environment](#development-environment) - [Set up a login route](#set-up-a-login-route) - [Create a re-usable layout component](#create-a-re-usable-layout-component) - [Create the sign in form](#create-the-sign-in-form) - [Build the form](#build-the-form) - [Create a form field component](#create-a-form-field-component) - [Add a sign up form](#add-a-sign-up-form) - [Store the form action in state](#store-the-form-action-in-state) - [Add toggleable fields](#add-toggleable-fields) - [The authentication flow](#the-authentication-flow) - [Build the register function](#build-the-register-function) - [Create an instance of `PrismaClient`](#create-an-instance-of-prismaclient) - [Update your data model](#update-your-data-model) - [Add a user service](#add-a-user-service) - [Build the login function](#build-the-login-function) - [Add session management](#add-session-management) - [Handle the login and register form submissions](#handle-the-login-and-register-form-submissions) - [Authorize users on private routes](#authorize-users-on-private-routes) - [Add form validation](#add-form-validation) - [Summary & What's next](#summary--whats-next) ## Introduction In the [last part](/fullstack-remix-prisma-mongodb-1-7D0BfTXBmB6r) of this series you set up your Remix project and got a MongoDB database up and running. You also configured TailwindCSS and Prisma and began to model out a `User` collection in your `schema.prisma` file. In this part you will implement authentication in your application, allowing a user to create an account and sign in via sign in and sign up forms. > **Note**: The starting point for this project is available in the [part-1](https://github.com/sabinadams/kudos-remix-mongodb-prisma/tree/part-1) branch of the GitHub repository. If you'd like to see the final result of this part, head over to the [part-2](https://github.com/sabinadams/kudos-remix-mongodb-prisma/tree/part-2) branch. ### Development environment In order to follow along with the examples provided, you will be expected to ... - ... have [Node.js](https://nodejs.org) installed. - ... have [Git](https://git-scm.com/downloads) installed. - ... have the [TailwindCSS VSCode Extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) installed. _(optional)_ - ... have the [Prisma VSCode Extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed. _(optional)_ > **Note**: The optional extensions add some really nice intellisense and syntax highlighting for Tailwind and Prisma. ## Set up a login route The very first thing you need to do to kick things off is set up a `/login` route where your sign in and sign up forms will live. To create a route within the Remix framework, add a file to the `app/routes` folder. The name of that file will be used as the name of the route. For more info on how routing works in Remix, check out their [docs](https://remix.run/docs/en/v1/tutorials/jokes#routes). Create a new file in `app/routes` named `login.tsx` with the following contents: ```tsx copy // app/routes/login.tsx export default function Login() { return (

Login Route

) } ``` The default export of a route file is the component Remix renders into the browser. Start the development server using `npm run dev` and navigate to [`http://localhost:3000/login`](http://localhost:3000/login), and you should see the route rendered. ![](/blog/posts/fullstack-mongodb-remix-2/initial-login.png) This works, but doesn't look very nice yet... Next you will spruce it up a bit by adding an actual sign in form. ## Create a re-usable layout component First, create a component you will wrap your routes in to provide some shared formatting and styling. You will use the [composition](https://reactjs.org/docs/composition-vs-inheritance.html) pattern to create this `Layout` component. ### Composition **Composition** is a pattern where you provide a component a set of child elements via its `props`. The `children` prop represents the elements defined between the opening and closing tag of the parent component. For example, consider this usage of a component named `Parent`: ```tsx copy

The child

``` In this case, the `

` tag is a child of the `Parent` component and will be rendered into the `Parent` component wherever you decide to render the `children` prop value. To see this in action, create a new folder inside the `app` folder named `components`. Inside of that folder create a new file named `layout.tsx`. In that file, export the following [function component](https://reactjs.org/docs/components-and-props.html): ```tsx copy // app/components/layout.tsx export function Layout({ children }: { children: React.ReactNode }) { return

{children}
} ``` This component uses Tailwind classes to specify you want anything wrapped in the component to take up the full width and height of the screen, use the mono font, and show a moderately dark blue as the background. Notice the `children` prop is rendered inside the `
`. To see how this will get rendered when put to use, check out the snippets below: ```tsx

Child Element

``` ```tsx

Child Element

```
## Create the sign in form Now you can import that component into the `app/routes/login.tsx` file and wrap your `

` tag inside of the new `Layout` component instead of the `
` where it currently lives: ```tsx copy // app/routes/login.tsx import { Layout } from '~/components/layout' export default function Login() { return (

Login Route

) } ``` ### Build the form Next add a sign in form that takes in `email` and `password` inputs and displays a submit button. Add a nice welcome message at the top to greet users when they enter your site and center the entire form on the screen using [Tailwind's flex classes](https://tailwindcss.com/docs/flex). ```tsx copy // app/routes/login.tsx import { Layout } from '~/components/layout' export default function Login() { return (

Welcome to Kudos!

Log In To Give Some Praise!

) } ``` ![](/blog/posts/fullstack-mongodb-remix-2/login-form.png) At this point, you don't need to worry about where the `
`'s action is pointing, just that it has a `method` value of `"post"`. Later on you will check out some cool Remix magic that sets up the action for us! ### Create a form field component The input fields and their labels will be re-written quite a bit throughout this application as you add more forms, so break those out into a [controlled component](https://reactjs.org/docs/forms.html#controlled-components) called `FormField` to avoid code duplication. Create a new file in `app/components` named `form-field.tsx` where you will build the `FormField` component. Then add the following code to get it started: ```tsx copy // app/components/form-field.tsx interface FormFieldProps { htmlFor: string label: string type?: string value: any onChange?: (...args: any) => any } export function FormField({ htmlFor, label, type = 'text', value, onChange = () => {} }: FormFieldProps) { return ( <> ) } ``` This will define and export the exact same label and input combination you had before in the sign in form, except this component will have configurable options: - `htmlFor`: The value to use for the `id` and `name` attributes of the input field, and the `htmlFor` attribute of the label. - `label`: The text to show in the label. - `value`: The current _controlled_ value of the input field. - `type`: _optional_ Allows you to set the input field's `type` attribute, but defaults to a value of `'text'`. - `onChange`: _optional_ Allows you to provide a function to run when the input field's value is changed. Defaults to an empty function call. You may now replace the existing labels and inputs with this component: ```tsx copy // app/routes/login.tsx import { useState } from 'react' import { Layout } from '~/components/layout' import { FormField } from '~/components/form-field' export default function Login() { const [formData, setFormData] = useState({ email: '', password: '', }) // Updates the form data when an input changes const handleInputChange = (event: React.ChangeEvent, field: string) => { setFormData(form => ({ ...form, [field]: event.target.value })) } return (

Welcome to Kudos!

Log In To Give Some Praise!

handleInputChange(e, 'email')} /> handleInputChange(e, 'password')} />
) } ``` This will import the new `FormField` component whose state will be managed by the parent _(the sign in form in this case)_. Any updates to the values will be tracked using the `handleInputChange` function. You will come back to the `FormField` component a little bit later to add error message handling, but this will do what it needs to for now! ## Add a sign up form You will also need a way for the user to sign up for an account, which means you'll need another form. This form will take in four values: - `email` - `password` - `firstName` - `lastName` To avoid having to create a new `/signup` route that looks _almost_ identical to the `/login` route, repurpose the sign in form so that it can be toggled between two different actions: login and register. ### Store the form action in state First you'll need some way for the user to be able to switch between forms and for your code to be able to differentiate between the forms. At the top of the `Login` component, create another variable in state to hold your `action`. ```tsx copy // app/routes/login.tsx export default function Login() { const [action, setAction] = useState('login') // ... } ``` > **Note**: The default state will be the login screen. Next you will need some way to switch change which state you want to view. Above the "Welcome to Kudos" message, add the following button: ```tsx copy // app/routes/login.tsx return (
{/* ... */}
) ``` This button's text will change based on the `action` state. The `onClick` method will toggle the state back and forth between `'login`' and `'register`' values. There are a few places with static text on this page that you will want to adjust depending on which form you are viewing. Specifically the "Log In To Give Some Praise!" sub-header and the "Sign In" button within the form itself. Change the form's sub-header to show a different message on each form: ```tsx diff copy // app/routes/login.tsx -

Log In To Give Some Praise!

+

+ {action === 'login' ? 'Log In To Give Some Praise!' : 'Sign Up To Get Started!'} +

``` Get rid of the _Sign In_ button altogether and replace it with the following ` ``` This new button has a `name` and a `value` attribute. The value is set to whatever the state's `action` is. When your form is submitted, this value will be passed as along with the form data as `_action`. > **Note**: This trick only works on a ` This example demonstrates how to create a Prisma Client extension that adds virtual / computed fields to a Prisma model. These fields are not included in the database, but rather are computed at runtime. Computed fields are type-safe and may return anything from simple values to complex objects, or even functions that can act as instance methods for your models. Computed fields must specify which other fields they depend on, and they may be composed / reused by other computed fields. ```typescript import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient() .$extends({ result: { user: { fullName: { needs: { firstName: true, lastName: true }, compute(user) { return `${user.firstName} ${user.lastName}`; }, }, }, }, }) .$extends({ result: { user: { displayName: { needs: { fullName: true, email: true }, compute(user) { return `${user.fullName} <${user.email}>`; }, }, }, }, }); ``` ```typescript const users = await prisma.user.findMany({ take: 5 }); for (const user of users) { console.info(`- ${user.displayName}`); } ``` ```prisma model User { id String @id @default(cuid()) firstName String lastName String email String } ``` ### Example: Transformed fields This example shows how to use a Prisma Client extension to transform fields in results returned by Prisma queries. In the example, a `date` field is transformed to a relative string for a specific locale. This shows a way to implement internationalization (i18n) at the data access layer in your application. However, this technique could allow you to implement any kind of custom transformation or serialization/deserialization of fields on your query results. ```typescript import { formatDistanceToNow } from "date-fns"; import { de } from "date-fns/locale"; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient().$extends({ result: { post: { createdAt: { needs: { createdAt: true }, compute(post) { return formatDistanceToNow(post.createdAt, { addSuffix: true, locale: de, }); }, }, }, }, }); ``` ```typescript const posts = await prisma.post.findMany({ take: 5 }); for (const post of posts) { console.info(`- ${post.title} (${post.createdAt})`); } ``` ```prisma model Post { id String @id @default(cuid()) title String createdAt DateTime @default(now()) } ``` ### Example: Obfuscated fields This example is a special case for the previous [Transformed fields](#example-transformed-fields) example. It uses an extension to hide a sensitive `password` field on a `User` model. The `password` column is not included in selected columns in the underlying SQL queries, and it will resolve to `undefined` when accessed on a user result object. It could also resolve to any other value, such as an obfuscated string like `"********"`. ```typescript import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient().$extends({ result: { user: { password: { needs: {}, compute() { return undefined; }, }, }, }, }); ``` ```typescript const user = await prisma.user.findFirstOrThrow(); console.info("Email: ", user.email); // "user@example.com" console.info("Password: ", user.password); // undefined ``` ```prisma model User { id String @id @default(cuid()) email String password String } ``` ### Example: Instance methods This example shows how to add an [Active Record](https://www.martinfowler.com/eaaCatalog/activeRecord.html)-like interface to Prisma result objects. It uses a `result` extension to add `save` and `delete` methods directly to `User` model objects returned by Prisma Client methods. This technique can be used to customize Prisma result objects with behavior, analogous to adding instance methods to model classes. ```typescript import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient().$extends({ result: { user: { save: { needs: { id: true, email: true }, compute({ id, email }) { return () => prisma.user.update({ where: { id }, data: { email } }); }, }, delete: { needs: { id: true }, compute({ id }) { return () => prisma.user.delete({ where: { id } }); }, }, }, }, }); ``` ```typescript const user = await prisma.user.create({ data: { email: "test@example.com" }, }); user.email = "updated@example.com"; await user.save(); await user.delete(); ``` ```prisma model User { id String @id @default(cuid()) email String } ``` ### Example: Static methods This example demonstrates how to create a Prisma Client extension that adds `signUp()` and `findManyByDomain()` methods to a User model. This technique can be used to abstract the logic for common queries / operations, create repository-like interfaces, or do anything you might do with a static class method. ```typescript import bcrypt from "bcryptjs"; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient().$extends({ model: { user: { async signUp(email: string, password: string) { const hash = await bcrypt.hash(password, 10); return prisma.user.create({ data: { email, password: { create: { hash, }, }, }, }); }, async findManyByDomain(domain: string) { return prisma.user.findMany({ where: { email: { endsWith: `@${domain}` } }, }); }, }, }, }); ``` ```typescript await prisma.user.signUp("user1@example1.com", "p4ssword"); await prisma.user.signUp("user2@example2.com", "s3cret"); const users = await prisma.user.findManyByDomain("example2.com"); ``` ```prisma model User { id String @id @default(cuid()) email String password Password? } model Password { hash String user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String @unique } ``` ### Example: Model filters This example demonstrates a Prisma Client extension which adds reusable filters for a model that can be composed and passed to a query's `where` condition. Complex, frequently used filtering conditions can be written once and accessed in many queries through the extended Prisma Client instance. ```typescript import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient().$extends({ model: { post: { unpublished: () => ({ published: false }), published: () => ({ published: true }), byAuthor: (authorId: string) => ({ authorId }), byAuthorDomain: (domain: string) => ({ author: { email: { endsWith: `@${domain}` } }, }), hasComments: () => ({ comments: { some: {} } }), hasRecentComments: (date: Date) => ({ comments: { some: { createdAt: { gte: date } } }, }), titleContains: (search: string) => ({ title: { contains: search } }), } satisfies Record Prisma.PostWhereInput>, }, }); ``` ```typescript const posts = await prisma.post.findMany({ where: { AND: [ prisma.post.published(), prisma.post.byAuthorDomain("prisma.io"), prisma.post.hasRecentComments(yesterday), prisma.post.titleContains("GraphQL"), ], }, }); ``` ```prisma model User { id String @id @default(cuid()) firstName String lastName String email String posts Post[] comments Comment[] } model Post { id String @id @default(cuid()) title String published Boolean authorId String author User @relation(fields: [authorId], references: [id], onDelete: Cascade) comments Comment[] } model Comment { id String @id @default(cuid()) text String createdAt DateTime @default(now()) commenterId String postId String commenter User @relation(fields: [commenterId], references: [id], onDelete: Cascade) post Post @relation(fields: [postId], references: [id], onDelete: Cascade) } ``` ### Example: Readonly client This example creates a client that only allows read operations like `findMany` and `count`, not write operations like `create` or `update`. Calling write operations will result in an error at runtime and at compile time with TypeScript. ```typescript import { Prisma, PrismaClient } from "@prisma/client"; const WRITE_METHODS = [ "create", "update", "upsert", "delete", "createMany", "updateMany", "deleteMany", ] as const; const ReadonlyClient = Prisma.defineExtension({ name: "ReadonlyClient", model: { $allModels: Object.fromEntries( WRITE_METHODS.map((method) => [ method, function (args: never) { throw new Error( `Calling the \`${method}\` method on a readonly client is not allowed` ); }, ]) ) as { [K in typeof WRITE_METHODS[number]]: ( args: `Calling the \`${K}\` method on a readonly client is not allowed` ) => never; }, }, }); const prisma = new PrismaClient(); const readonlyPrisma = prisma.$extends(ReadonlyClient); ``` ```typescript const posts = await readonlyPrisma.post.findMany({ take: 5 }); console.log(posts); // @ts-expect-error: // Argument of type '{ data: { title: string; published: boolean; }; }' // is not assignable to parameter of type '"Calling the `create` method // on a readonly client is not allowed"'. await readonlyPrisma.post.create({ data: { title: "New post", published: false }, }); ``` ```prisma model Post { id String @id @default(cuid()) title String published Boolean } ``` ### Example: Input transformation This example creates an extended client instance which modifies query arguments to only include `published` posts. Since `query` extensions allow modifying query arguments, it's possible to apply various kinds of default filters with this approach. ```typescript const prisma = new PrismaClient().$extends({ query: { post: { $allOperations({ args, query, operation }) { // Do nothing for `create` if (operation === "create") { return query(args); } // Refine the type - methods other than `create` accept a `where` clause args = args as Extract; // Augment the `where` clause with `published: true` return query({ ...args, where: { ...args.where, published: true, }, }); }, }, }, }); ``` ```typescript const publishedPostsCount = await prisma.post.count(); ``` ```prisma model Post { id String @id @default(cuid()) title String published Boolean } ``` ### Example: Input validation This example uses Prisma Client extensions to perform custom runtime validations when creating and updating database objects. It uses a [Zod](https://github.com/colinhacks/zod) runtime schema to check that the data passed to Prisma write methods is valid. This could be used to sanitize user input or otherwise deny mutations that do not meet some criteria defined by your business logic rules. ```typescript import { Prisma, PrismaClient } from "@prisma/client"; import { ProductCreateInput } from "./schemas"; const prisma = new PrismaClient().$extends({ query: { product: { create({ args, query }) { args.data = ProductCreateInput.parse(args.data); return query(args); }, update({ args, query }) { args.data = ProductCreateInput.partial().parse(args.data); return query(args); }, updateMany({ args, query }) { args.data = ProductCreateInput.partial().parse(args.data); return query(args); }, upsert({ args, query }) { args.create = ProductCreateInput.parse(args.create); args.update = ProductCreateInput.partial().parse(args.update); return query(args); }, }, }, }); ``` ```typescript import { z } from "zod"; import { Prisma } from "@prisma/client"; export const ProductCreateInput = z.object({ slug: z .string() .max(100) .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/), name: z.string().max(100), description: z.string().max(1000), price: z .instanceof(Prisma.Decimal) .refine((price) => price.gte("0.01") && price.lt("1000000.00")), }) satisfies z.Schema; ``` ```typescript // Valid product const product = await prisma.product.create({ data: { slug: "example-product", name: "Example Product", description: "Lorem ipsum dolor sit amet", price: new Prisma.Decimal("10.95"), }, }); // Invalid product try { await prisma.product.create({ data: { slug: "invalid-product", name: "Invalid Product", description: "Lorem ipsum dolor sit amet", price: new Prisma.Decimal("-1.00"), }, }); } catch (err: any) { console.log(err?.cause?.issues); } ``` ```prisma model Product { id String @id @default(cuid()) slug String name String description String price Decimal reviews Review[] } model Review { id String @id @default(cuid()) body String stars Int product Product @relation(fields: [productId], references: [id], onDelete: Cascade) productId String } ``` ### Example: JSON Field Types This next example combines the approaches shown in the [Input validation](#example-input-validation) and [Transformed fields](#example-transformed-fields) examples to provide static and runtime types for a `Json` field. It uses [Zod](https://github.com/colinhacks/zod) to parse the field data and infer static TypeScript types. This example includes a `User` model with a JSON profile field, which has a sparse structure that may vary between users. The extension has two parts: - A `result` extension that adds a computed `profile` field. This field uses the `Profile` Zod schema to parse the underlying untyped `profile` field. TypeScript infers the static data type from the parser, so query results have both static and runtime type safety. - A `query` extension that parses the `profile` field on input data for the `User` model's write methods like `create` and `update`. ```typescript import { Prisma, PrismaClient } from "@prisma/client"; import { Profile } from "./schemas"; const prisma = new PrismaClient().$extends({ result: { user: { profile: { needs: { profile: true }, compute({ profile }) { return Profile.parse(profile); }, }, }, }, query: { user: { create({ args, query }) { args.data.profile = Profile.parse(args.data.profile); return query(args); }, createMany({ args, query }) { const users = Array.isArray(args.data) ? args.data : [args.data]; for (const user of users) { user.profile = Profile.parse(user.profile); } return query(args); }, update({ args, query }) { if (args.data.profile !== undefined) { args.data.profile = Profile.parse(args.data.profile); } return query(args); }, updateMany({ args, query }) { if (args.data.profile !== undefined) { args.data.profile = Profile.parse(args.data.profile); } return query(args); }, upsert({ args, query }) { args.create.profile = Profile.parse(args.create.profile); if (args.update.profile !== undefined) { args.update.profile = Profile.parse(args.update.profile); } return query(args); }, }, }, }); ``` ```typescript import { z } from "zod"; export type Avatar = z.infer; export const Avatar = z.object({ url: z.string().url(), crop: z.object({ top: z.number().min(0).max(1), right: z.number().min(0).max(1), bottom: z.number().min(0).max(1), left: z.number().min(0).max(1), }), }); export type Address = z.infer; export const Address = z.object({ street: z.string(), city: z.string(), region: z.string(), postalCode: z.string(), country: z.string(), }); export type ContactInfo = z.infer; export const ContactInfo = z .object({ email: z.string().email(), phone: z.string(), address: Address, }) .partial(); export type SocialLinks = z.infer; export const SocialLinks = z .object({ twitter: z.string().url(), github: z.string().url(), website: z.string().url(), linkedin: z.string().url(), }) .partial(); export type Profile = z.infer; export const Profile = z .object({ firstName: z.string(), lastName: z.string(), avatar: Avatar, contactInfo: ContactInfo, socialLinks: SocialLinks, }) .partial(); ``` ```typescript import * as runtime from "@prisma/client/runtime/index"; import { UserPayload } from "@prisma/client"; const users = await prisma.user.findMany({ take: 10 }); users.forEach(renderUser); type ExtArgs = UserPayload; type User = runtime.Types.GetResult; function renderUser(user: User) { // ... } ``` ```prisma model User { id String @id @default(cuid()) email String @unique profile Json } ``` ### Example: Query logging This example shows how to use Prisma Client extensions to perform similar tasks to [middleware](https://www.prisma.io/docs/concepts/components/prisma-client/middleware). In this example, a `query` extension tracks the time it takes to fulfill each query, and logs the results along with the query and arguments themselves. This technique could be used to perform generic logging, emit events, track usage, etc. > **Note**: You may be interested in the [OpenTelemetry tracing](https://www.prisma.io/docs/concepts/components/prisma-client/opentelemetry-tracing) and [Metrics](https://www.prisma.io/docs/concepts/components/prisma-client/metrics) features (both in Preview), which provide detailed insights into performance and how Prisma interacts with the database. ```typescript import { PrismaClient } from "@prisma/client"; import { performance } from "perf_hooks"; import * as util from "util"; const prisma = new PrismaClient().$extends({ query: { $allModels: { async $allOperations({ operation, model, args, query }) { const start = performance.now(); const result = await query(args); const end = performance.now(); const time = end - start; console.log( util.inspect( { model, operation, args, time }, { showHidden: false, depth: null, colors: true } ) ); return result; }, }, }, }); ``` ```typescript await prisma.user.findMany({ orderBy: [{ lastName: "asc" }, { firstName: "asc" }], take: 5, }); await prisma.user.groupBy({ by: ["lastName"], _count: true }); ``` ```prisma model User { id String @id @default(cuid()) firstName String lastName String } ``` ### Example: Retry transactions This example shows how to use a Prisma Client extension to automatically retry transactions that fail due to a write conflict / deadlock timeout. Failed transactions will be retried with [exponential backoff and jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) to reduce contention under heavy traffic. ```typescript import { backOff, IBackOffOptions } from "exponential-backoff"; import { Prisma, PrismaClient } from "@prisma/client"; function RetryTransactions(options?: Partial) { return Prisma.defineExtension((prisma) => prisma.$extends({ client: { $transaction(...args: any) { return backOff(() => prisma.$transaction.apply(prisma, args), { retry: (e) => { // Retry the transaction only if the error was due to a write conflict or deadlock // See: https://www.prisma.io/docs/reference/api-reference/error-reference#p2034 return e.code === "P2034"; }, ...options, }); }, } as { $transaction: typeof prisma["$transaction"] }, }) ); } const prisma = new PrismaClient().$extends( RetryTransactions({ jitter: "full", numOfAttempts: 5, }) ); ``` ```typescript // If one or more transactions fail due to deadlock / write conflict, // the entire transaction will be retried up to 5 times. await Promise.allSettled([ prisma.$transaction(tx => { // ... }), prisma.$transaction(tx => { // ... }), prisma.$transaction(tx => { // ... }), ]); ``` ```prisma model User { id String @id @default(cuid()) firstName String lastName String } ``` ### Example: Callback-free interactive transactions This example shows a Prisma Client extension which adds a new API for starting [interactive transactions](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#interactive-transactions) without callbacks. This gives you the full power of [interactive transactions](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#interactive-transactions) (such as read–modify–write cycles), but in a more imperative API. This may be more convenient than the normal callback-style API for interactive transactions in some scenarios. ```typescript import { Prisma, PrismaClient } from "@prisma/client"; type FlatTransactionClient = Prisma.TransactionClient & { $commit: () => Promise; $rollback: () => Promise; }; const ROLLBACK = { [Symbol.for("prisma.client.extension.rollback")]: true }; const prisma = new PrismaClient().$extends({ client: { async $begin() { const prisma = Prisma.getExtensionContext(this); let setTxClient: (txClient: Prisma.TransactionClient) => void; let commit: () => void; let rollback: () => void; // a promise for getting the tx inner client const txClient = new Promise((res) => { setTxClient = (txClient) => res(txClient); }); // a promise for controlling the transaction const txPromise = new Promise((_res, _rej) => { commit = () => _res(undefined); rollback = () => _rej(ROLLBACK); }); // opening a transaction to control externally if ( "$transaction" in prisma && typeof prisma.$transaction === "function" ) { const tx = prisma.$transaction((txClient) => { setTxClient(txClient); return txPromise.catch((e) => { if (e === ROLLBACK) return; throw e; }); }); // return a proxy TransactionClient with `$commit` and `$rollback` methods return new Proxy(await txClient, { get(target, prop) { if (prop === "$commit") { return () => { commit(); return tx; }; } if (prop === "$rollback") { return () => { rollback(); return tx; }; } return target[prop as keyof typeof target]; }, }) as FlatTransactionClient; } throw new Error("Transactions are not supported by this client"); }, }, }); ``` ```typescript const tx = await prisma.$begin(); const user = await tx.user.findFirstOrThrow(); await tx.user.update(/* ... */); await tx.$commit(); // Or: await tx.$rollback(); ``` ```prisma model User { id String @id @default(cuid()) firstName String lastName String email String } ``` ### Example: Audit log context This example shows how to use a Prisma Client extension to provide the current application user's ID as context to an audit log trigger in Postgres. User IDs are included in an audit trail tracking every change to rows in a table. A detailed explanation of this solution can be found in [the example's `README` on GitHub](https://github.com/prisma/prisma-client-extensions/tree/main/audit-log-context). ```typescript import { Prisma, PrismaClient } from "@prisma/client"; function forUser(userId: number) { return Prisma.defineExtension((prisma) => prisma.$extends({ query: { $allModels: { async $allOperations({ args, query }) { const [, result] = await prisma.$transaction([ prisma.$executeRaw`SELECT set_config('app.current_user_id', ${userId.toString()}, TRUE)`, query(args), ]); return result; }, }, }, }) ); } ``` ```typescript const prisma = new PrismaClient(); const user = await prisma.user.findFirstOrThrow(); const product = await prisma.product.findFirstOrThrow(); const userPrisma = prisma.$extends(forUser(user.id)); await userPrisma.product.update({ where: { id: product.id }, data: { name: "Updated Name" }, }); ``` ```prisma model User { id Int @id @default(autoincrement()) email String productVersions ProductVersion[] @@schema("public") } model Product { id Int @id @default(autoincrement()) name String versions ProductVersion[] @@schema("public") } enum AuditOperation { INSERT UPDATE DELETE @@schema("audit") } model ProductVersion { // Version metadata fields versionId Int @id @default(autoincrement()) versionOperation AuditOperation versionProductId Int? versionUserId Int? versionTimestamp DateTime // Mirrored fields from the Product table id Int name String product Product? @relation(fields: [versionProductId], references: [id]) user User? @relation(fields: [versionUserId], references: [id]) @@schema("audit") } ``` ```sql -- Product audit trigger function CREATE OR REPLACE FUNCTION "audit"."Product_audit"() RETURNS TRIGGER AS $$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO "audit"."ProductVersion" VALUES (DEFAULT, 'DELETE', NULL, current_setting('app.current_user_id', TRUE)::int, now(), OLD.*); ELSIF (TG_OP = 'UPDATE') THEN INSERT INTO "audit"."ProductVersion" VALUES (DEFAULT, 'UPDATE', NEW."id", current_setting('app.current_user_id', TRUE)::int, now(), NEW.*); ELSIF (TG_OP = 'INSERT') THEN INSERT INTO "audit"."ProductVersion" VALUES (DEFAULT, 'INSERT', NEW."id", current_setting('app.current_user_id', TRUE)::int, now(), NEW.*); END IF; RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER audit AFTER INSERT OR UPDATE OR DELETE ON "public"."Product" FOR EACH ROW EXECUTE FUNCTION "audit"."Product_audit"(); ``` ### Example: Row level security This example shows how to use a Prisma Client extension to isolate data between tenants in a multi-tenant app using Row Level Security (RLS) in Postgres. A detailed explanation of this solution can be found in [the example's `README` on GitHub](https://github.com/prisma/prisma-client-extensions/tree/main/row-level-security). ```typescript import { Prisma, PrismaClient } from "@prisma/client"; function bypassRLS() { return Prisma.defineExtension((prisma) => prisma.$extends({ query: { $allModels: { async $allOperations({ args, query }) { const [, result] = await prisma.$transaction([ prisma.$executeRaw`SELECT set_config('app.bypass_rls', 'on', TRUE)`, query(args), ]); return result; }, }, }, }) ); } function forCompany(companyId: string) { return Prisma.defineExtension((prisma) => prisma.$extends({ query: { $allModels: { async $allOperations({ args, query }) { const [, result] = await prisma.$transaction([ prisma.$executeRaw`SELECT set_config('app.current_company_id', ${companyId}, TRUE)`, query(args), ]); return result; }, }, }, }) ); } ``` ```typescript const prisma = new PrismaClient(); const user = await prisma.$extends(bypassRLS()).user.findFirstOrThrow(); const companyPrisma = prisma.$extends(forCompany(user.companyId)); const projects = await companyPrisma.project.findMany({ include: { owner: true, tasks: { include: { assignee: true, }, }, }, }); invariant(projects.every((project) => project.companyId === user.companyId)); ``` ```prisma model Company { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid name String users User[] projects Project[] tasks Task[] } model User { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid companyId String @default(dbgenerated("(current_setting('app.current_company_id'::text))::uuid")) @db.Uuid email String @unique company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) ownedProjects Project[] assignedTasks Task[] } model Project { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid companyId String @default(dbgenerated("(current_setting('app.current_company_id'::text))::uuid")) @db.Uuid userId String? @db.Uuid title String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) owner User? @relation(fields: [userId], references: [id], onDelete: SetNull) tasks Task[] } enum TaskStatus { Pending InProgress Complete WontDo } model Task { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid companyId String @default(dbgenerated("(current_setting('app.current_company_id'::text))::uuid")) @db.Uuid projectId String @db.Uuid userId String? @db.Uuid title String status TaskStatus company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) project Project @relation(fields: [projectId], references: [id], onDelete: Cascade) assignee User? @relation(fields: [userId], references: [id], onDelete: SetNull) } ``` ```sql -- Enable Row Level Security ALTER TABLE "Company" ENABLE ROW LEVEL SECURITY; ALTER TABLE "User" ENABLE ROW LEVEL SECURITY; ALTER TABLE "Project" ENABLE ROW LEVEL SECURITY; ALTER TABLE "Task" ENABLE ROW LEVEL SECURITY; -- Force Row Level Security for table owners ALTER TABLE "Company" FORCE ROW LEVEL SECURITY; ALTER TABLE "User" FORCE ROW LEVEL SECURITY; ALTER TABLE "Project" FORCE ROW LEVEL SECURITY; ALTER TABLE "Task" FORCE ROW LEVEL SECURITY; -- Create row security policies CREATE POLICY tenant_isolation_policy ON "Company" USING ("id" = current_setting('app.current_company_id', TRUE)::uuid); CREATE POLICY tenant_isolation_policy ON "User" USING ("companyId" = current_setting('app.current_company_id', TRUE)::uuid); CREATE POLICY tenant_isolation_policy ON "Project" USING ("companyId" = current_setting('app.current_company_id', TRUE)::uuid); CREATE POLICY tenant_isolation_policy ON "Task" USING ("companyId" = current_setting('app.current_company_id', TRUE)::uuid); -- Create policies to bypass RLS (optional) CREATE POLICY bypass_rls_policy ON "Company" USING (current_setting('app.bypass_rls', TRUE)::text = 'on'); CREATE POLICY bypass_rls_policy ON "User" USING (current_setting('app.bypass_rls', TRUE)::text = 'on'); CREATE POLICY bypass_rls_policy ON "Project" USING (current_setting('app.bypass_rls', TRUE)::text = 'on'); CREATE POLICY bypass_rls_policy ON "Task" USING (current_setting('app.bypass_rls', TRUE)::text = 'on'); ``` ## Tell us what you think We hope you are as excited as we are about the possibilities that Prisma Client extensions create! 💡 You can share your feedback with us in [this GitHub issue](https://github.com/prisma/prisma/issues/16500). --- ## [Prisma Adopts Semantic Versioning (SemVer)](/blog/prisma-adopts-semver-strictly) **Meta Description:** We are adjusting Prisma's release policy to adhere more strictly to Semantic Versioning. In the future, breaking changes in the stable development surface (General Availability) will only be rolled out in major version increments. **Content:** ## TL;DR Here is a brief overview of the new rules we are putting in place: - By adopting SemVer, we're making it easier for users to understand which version may contain breaking changes. The adoption of SemVer is merely a change to our release policy to be consistent with industry practices and improve the developer experience. - Breaking changes in stable surface (i.e. [General Availability](https://www.prisma.io/docs/about/prisma/releases#generally-available-ga)) will only be introduced in new _major versions_. - Breaking changes can still be rolled out in _minor versions_ but only for opt-in Preview and Early Access features that are not active by default (e.g. via a Preview feature flag or a specific opt-in option or new CLI command). - Opt-in breaking changes, i.e. Preview and Early Access, released in _minor versions_ will only be promoted to General Availability (no requirement for opt-in) in new _major versions_. You can read more details about this in the [Releases and maturity levels](https://www.prisma.io/docs/about/prisma/releases) section in our [documentation](https://www.prisma.io/). ## Prisma releases adopt SemVer [Semantic Versioning](https://semver.org/) (SemVer) is a conventional release strategy that has clear rules for when users can expect breaking changes in a software release. While we already followed the 3-digit SemVer _notation_ for Prisma releases, we didn't quite follow the actual SemVer _semantics_ yet. This meant that we sometimes released breaking changes upon _minor_ version increments. In the future, breaking changes in _minor_ version increments will always be opt-in. Any breaking change to the stable developer surface of the Prisma ORM will only happen in _major_ version increments. Currently, it's hard for users to understand which version may or not contain breaking changes. When upgrading through multiple versions, e.g. from `2.13.0` to `2.26.0`, you have to read the release notes of each intermediate release to determine which breaking changes will impact you – this makes it hard to navigate breaking changes. ## What this means for you? In essence, the new release policy doesn't change anything about how you use Prisma and the ongoing evolution of Prisma. We're just making it easier for you to understand which version may contain breaking changes. Prisma will continue to document the exact details for upcoming breaking changes in the release notes. Additionally, we will provide upgrade guides to help with the upgrade path between major releases. Many of the package managers and dependency automation tools in the industry were designed with SemVer in mind, e.g. [Renovate](https://renovatebot.com/) and [Dependabot](https://dependabot.com/). They save you time by automating parts of the dependency upgrade process, creating pull requests with relevant release changes, and automatically merging non-breaking changes. ## Why we are adopting SemVer semantics Updating dependencies can be a time-consuming process – especially in projects with many dependencies. **Adhering to Semver should improve your upgrade experience as breaking changes become predictable and visible moving forward.** SemVer is a widely used industry standard, especially in the Node.js ecosystem. As we're seeing more developers and companies adopt Prisma and getting helpful feedback about our release strategy, we've decided to adjust our release strategy and fully adopt SemVer in the future. ## One of Prisma's upcoming releases will have breaking changes One of the upcoming Prisma [releases](https://github.com/prisma/prisma) will come with breaking changes. Following our new release strategy, the _major_ version number will be incremented, and Prisma's new version will therefore be `3.x.x`. You can read more about our release strategy in the [documentation](https://www.prisma.io/docs/about/prisma/releases). --- ## [Enabling CORS for Express-GraphQL & Apollo Server | Prisma](/blog/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d) **Meta Description:** No description available. **Content:** ## What is CORS? _Cross-origin resource sharing_, short [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), is a protection mechanism for web pages, allowing the browser to safely load resources from domains that are different from the one it originally loaded the page from. As an example, say you’re accessing `https://www.prisma.io/` in your browser. The browser downloads the HTML and JavaScript for the site in order to render it for you. Now, some data to be displayed on the site actually is stored somewhere else, on a different server — a _different origin_. > Two URLs are said to have the same origin if the following three properties are identical for them: domain, protocol and port: > `http://localhost:3000`, `ws://localhost:3000` and `http://localhost:4000` all have **different origins**. > `http://localhost:3000` and `http://localhost:3000/graphql` have the **same origin**. In order for your browser to load the data from that other server, the other server needs to set `Access-Control` headers properly in order to determine its policy regarding cross-origin resource access. For example, by simply specifying `Access-Control-Allow-Origin: *`, the server indicates to the browser that it will allow CORS anywhere. ## How about an example Now, imagine the following scenario. You’re starting out with a new project and for now are only developing locally on your machine. You used [`create-react-app`](https://github.com/facebookincubator/create-react-app) to bootstrap your frontend and for the backend you setup a simple [express.js](https://github.com/expressjs) server (either based on [`express-graphql`](https://github.com/graphql/express-graphql), [`graphql-yoga`](https://github.com/prismagraphql/graphql-yoga) or [`apollo-server`](https://github.com/apollographql/apollo-server)). In fact, we prepared an [example](https://github.com/nikolasburk/graphql-cors-example) that mimics this exact scenario: ### Server ```js const express = require('express') const bodyParser = require('body-parser') const cors = require('cors') const { graphqlExpress, graphiqlExpress } = require('apollo-server-express') const { makeExecutableSchema } = require('graphql-tools') const typeDefs = ` type Query { hello(name: String): String! } ` const resolvers = { Query: { hello: (_, { name }) => `Hello ${name || 'World'}`, }, } const myGraphQLSchema = makeExecutableSchema({ typeDefs, resolvers }) const PORT = 4000 const app = express() // app.use(cors()) // not having cors enabled will cause an access control error app.use('/graphql', bodyParser.json(), graphqlExpress({ schema: myGraphQLSchema })) app.get('/graphiql', graphiqlExpress({ endpointURL: '/graphql' })) console.log(`Server listening on http://localhost:${PORT} ...`) app.listen(PORT) ``` > Notice that line 23 is commented out — CORS is not enabled! ### Frontend ```js import React from 'react' import ReactDOM from 'react-dom' import './index.css' import App from './App' import registerServiceWorker from './registerServiceWorker' import { ApolloProvider } from 'react-apollo' import { ApolloClient, HttpLink, InMemoryCache } from 'apollo-client-preset' const httpLink = new HttpLink({ uri: 'http://localhost:4000/graphql' }) const client = new ApolloClient({ link: httpLink, cache: new InMemoryCache(), }) ReactDOM.render( , document.getElementById('root'), ) registerServiceWorker() ``` > Standard setup for using Apollo Client 2.0 ```js import React, { Component } from 'react' import logo from './logo.svg' import './App.css' import gql from 'graphql-tag' import { graphql } from 'react-apollo' class App extends Component { render() { if (this.props.data.loading) { return
Loading
} return (

{this.props.data.hello}

) } } export default graphql( gql` { hello } `, )(App) ``` > The `App` component sends a simple `hello` query using Apollo Client In your local development setup, where the React app is loaded from [`http://localhost:3000`](http://localhost:3000) and the GraphQL server is serving at [`http://localhost:4000`](http://localhost:4000)/graphql, you’ll now get an access control error if you’re trying to run the app: ![](https://cdn-images-1.medium.com/max/2452/1*ZbsVGATAeIp5iU2504VP2A.png) What exactly is the issue when CORS is not enabled? Well, CORS is in fact a _specification_ for a communication flow between client (a browser) and server. In some situations, this flow requires the server to process HTTP [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) requests as can be seen from this flowchart: ![The CORS flow might required additional HTTP requests with the [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) method ([source](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#/media/File:Flowchart_showing_Simple_and_Preflight_XHR.svg))](https://cdn-images-1.medium.com/max/2956/1*m6QGz5tXtLt7uVapNCpBEw.png)_The CORS flow might required additional HTTP requests with the [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) method ([source](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#/media/File:Flowchart_showing_Simple_and_Preflight_XHR.svg))_ The problem is that neither `express-graphql` nor `apollo-server` accept HTTP requests other than GET and POST — which is why the request fails in our scenario. This is also indicated by the error message we saw in the console: `OPTIONS [http://localhost:4000](http://localhost:4000) 405 (Method not allowed)`. > [Here](https://github.com/graphql/express-graphql/issues/14) is the GitHub discussion on `express-graphql` where this issue first came up. Luckily, the solution is very simple. As `express-graphql` and `apollo-server` are both based on [express.js](https://github.com/expressjs), you can simply use its standard [cors](https://github.com/expressjs/cors#configuration-options) middleware to fix the issue. Uncommenting [line 23](https://github.com/nikolasburk/graphql-cors-example/blob/master/server/index.js#L23) in `server.js` will enable the cors middleware for your express server: `app.use(cors())`. Having the middleware enabled ensures your express server sets the proper HTTP header, enabling your React app to load data from it: ![Using the [cors](https://github.com/expressjs/cors) middleware, the server sets the correct HTTP header enabling cross-origin resource sharing](https://cdn-images-1.medium.com/max/2096/1*LnVsDQuQtSl-Wt-m6DfO5g.png)_Using the [cors](https://github.com/expressjs/cors) middleware, the server sets the correct HTTP header enabling cross-origin resource sharing_ ## Summary CORS is an important protection mechanism preventing websites from downloading malicious resources, but from a developer standpoint [it can be a pain to properly configure it](https://devrant.com/rants/133438/i-seriously-dont-understand-cors-fml-i-tried-to-access-the-web-api-i-found-onlin). When using `express-graphql` and `apollo-server`, all you need to do is include the standard [cors](https://github.com/expressjs/cors) middleware used in express.js apps and you’re good to go: ```js // other imports ... const cors = require('cors') const app = express() app.use(cors()) // enable `cors` to set HTTP response header: Access-Control-Allow-Origin: * app.use('/graphql', bodyParser.json(), graphqlExpress({ schema })) app.listen(PORT) ``` --- ## [Prisma Accelerate now in General Availability](/blog/accelerate-ga-release-I9cQM6bSf2g6) **Meta Description:** Supercharge your applications with Prisma Accelerate's scalable connection pooling and global edge caching. Plus, enjoy our exclusive launch offer. **Content:** Developing data-driven applications comes with its challenges, and efficient database connections and swift data retrieval are essential. The Prisma ORM is key for database access and now, with Prisma Accelerate, we provide a solution that offers not only global connection pooling across 16 regions but also edge caching. It guarantees efficient and low-latency database interactions. ## What is Prisma Accelerate? - **Evolved Connection Pooling**: Available in 16 regions globally, Prisma Accelerate’s connection pooler ensures reliability and efficient database interactions, regardless of the database's geographical location. - **Global Edge Caching:** Improve data retrieval speeds by caching frequently accessed data in over 280 locations worldwide, reducing the latency for repetitive database queries. ### Pricing Prisma Accelerate is priced based on your usage, and our Starter, Pro, and Business plans are now available to everyone. You can get started for free and only pay for what you need with full control over your costs, which we calculate based on the number of requests and your egress. To see the specifics of each plan, and to find the perfect fit for your needs, explore our detailed [Pricing page](https://www.prisma.io/pricing). > **Launch Special until Nov 12, 2023** - As part of Prisma Accelerate’s GA launch, we're excited to celebrate with you and offer a **50% lifetime discount** on the base price of our Pro and Business plans when you subscribe by November 12, 2023. ## Prisma Accelerate in Production To see what Prisma Accelerate can do, let's take a look at its implementation in two real-world cases: ### Cal.com: Enhancing scheduling efficiency The logo of Cal.com [Cal.com](https://cal.com/), a popular open-source scheduling platform, provides appointment bookings for a diverse range of users. Given the high frequency of appointments scheduled every minute, they recognized the importance of swift database access in delivering the best user experience, especially during peak times. Prisma Accelerate's robust connection pooling is designed to handle high volumes of database interactions efficiently. For platforms like Cal.com, this means over 4M queries every day to enable seamless management of appointments, even with heavy traffic peaks. Prisma Accelerate seamlessly complements our platform, powering Cal.com to handle millions of database queries every day, across our global user base. ### Formbricks: Privacy-first survey suite The logo of Formbricks [Formbricks](https://formbricks.com/), an open-source experience management platform, streamlines user interactions, understanding their sentiments toward products. As a tool that facilitates real-time insights through surveys and feedback, swift and reliable database interactions are crucial. Leveraging Prisma Accelerate's connection pooling, Formbricks achieves seamless and rapid data access, with high-traffic peaking at 7M queries in a 24-hour time period. This allows them to maintain consistent performance, even when faced with unpredictable user traffic, ensuring a smooth experience for all their users. Thanks to Prisma Accelerate, we can seamlessly scale our serverless applications without concerns about data layer performance. ## Prisma Accelerate and the Data DX Vision With the rise in data complexity, developers encounter mounting challenges in managing, integrating, and deploying data-centric solutions. [Data DX](https://datadx.io) champions a simplified approach to data-driven application development, avoiding unnecessary complexity while retaining depth and detail. Prisma Accelerate aligns perfectly with this philosophy, serving as a pivotal tool in our Data DX journey.
### Time to get started We are incredibly excited about Prisma Accelerate and can't wait to see what you’ll build with it. As you dive in, please share your thoughts, engage with us on [Discord](https://pris.ly/discord), and let's build amazing data-driven applications together!
--- ## [New Tooling to Improve Your GraphQL Workflows](/blog/new-tooling-to-improve-your-graphql-workflows-7240c81e1ba3) **Meta Description:** No description available. **Content:** > ⚠️ **This article is outdated!** The `graphql-config` and `graphql-cli` projects have been [handed over to the Guild](https://www.prisma.io/blog/the-guild-takes-over-oss-libraries-vvluy2i4uevs) in the meantime. ⚠️ ## Fragmentation in GraphQL Tooling Despite being a relatively young technology, GraphQL already has seen a great amount of adoption. With the growing number of projects that are using GraphQL, it gets more and more important for the community to develop standards and unify solutions to common problems that developers encounter in GraphQL projects. One of these problems is the question [how to write configuration files](https://github.com/graphcool/graphql-config/issues/16) in a way that _all_ dependent tools can understand them. If you’ve already worked on a larger GraphQL project, chances are you had to configure some of your tooling with information about your GraphQL schema. Just taking three popular tools as an example, all of them are using different configuration formats to specify where your schema is located: - For [eslint-plugin-graphql](https://github.com/apollostack/eslint-plugin-graphql), you need to reference your schema from .eslintrc - [GraphQL Language services](https://github.com/graphql/graphql-language-service) uses its own custom config format - [js-graphql-intellij-plugin](https://github.com/jimkyndemeyer/js-graphql-intellij-plugin) uses another custom config format With the growing number of tools relying on the schema, more and more different configuration files and formats are needed. The problem of fragmented configuration gets even more complex with more specific use cases, like using different environments for dev and production or adding additional endpoints for subscription servers. The solution? There needs to be a standard for how to configure GraphQL projects. ![](https://cdn-images-1.medium.com/max/2200/0*zy8sNGj9yqANZhrw.) ## .graphqlconfig - One Config to Rule Them All The format specified by [graphql-config](https://github.com/graphcool/graphql-config) will be the foundation for all schema-aware GraphQL tools. Here's a minimal example of what a .graphqlconfig can look like given a SDL-based schema file: ```json { "schemaPath": "./schema.graphql" } ``` Note that the referenced schema file might as well be in JSON format (as would be the case if it was generated based on the introspection dump from the GraphQL server). In more complex setups, you might want to configure additional endpoints for multiple environments or for a subscription server: ```json { "schemaPath": "schema.graphql", "extensions": { "endpoints": { "prod": { "url": "https://api.graph.cool/simple/v1/swapi", "subscription": { "url": "wss://subscriptions.graph.cool/simple/v1/swapi" } }, "dev": { "url": "http://localhost:3000/graphql", "subscription": { "url": "ws://localhost:3001" } } } } } ``` For a complete overview of the different options that can be used in a .graphqlconfig, you can refer to the full [specification](https://github.com/graphcool/graphql-config/blob/master/specification.md#use-cases). ## graphql-cli - The Swiss Army Knife for your GraphQL Project Along with the unified way to write configuration files, we’re also introducing a command-line tool to improve your local GraphQL development workflow: [graphql-cli](https://github.com/graphcool/graphql-cli). You can use it to quickly download the schema from a specific endpoint, open a GraphQL playground or show the schema diff between two different environments. Here is the CLI in action: ![](https://cdn-images-1.medium.com/max/2000/0*c56E4V22_pl88Si4.) You can simply install the CLI using npm: npm install -g graphql-cli The CLI ships with a plugin system so you can easily add commands to match your development workflow. You can for example check out the [GraphQL Voyager plugin](https://github.com/graphcool/graphql-cli-voyager). ## Continuously Improving Developer Experience With a unified format to write GraphQL configuration files as well as a CLI that supports common development workflows, the GraphQL tooling space sees two major additions. These are going to improve developer experience and lay the foundation for better interoperability of relevant tools in the future. ### Get Involved graphql-config and the graphql-cli are both community projects and as such will provide the most value if many people collaborate on them! **If you’re the author or maintainer of a GraphQL library or another related tool, we encourage you to adopt the graphql-config standard.** Please link to this [GitHub issue](https://github.com/graphcool/graphql-config/issues/27) to track the progress. As mentioned before, the graphql-cli can be extended with plugins to support custom use cases. **Feel free to start building your own plugins to support your GraphQL development workflow or tackle further use cases.** Ideas for more features could be plugins for code generation or letting people quickly spin up their own GraphQL server with graphql-up. We're excited to see what you're going to build! --- ## [Prisma Postgres®: Building a Modern PostgreSQL Service Using Unikernels & MicroVMs](/blog/announcing-prisma-postgres-early-access) **Meta Description:** At Prisma, we believe that deploying a database should be as simple as adding a new page in Notion. Today, we are excited to share the first milestone towards this vision: Prisma Postgres® gives developers an always-on database with pay-as-you-go pricing, thanks to our unique architecture design. **Content:** ## TL;DR We are excited to announce Prisma Postgres, **a managed PostgreSQL service that gives developers an _always-on_ database with _pay-as-you-go_ pricing for storage and queries** (no fixed cost, no cost for compute). It's like a serverless database — but without cold starts and a generous free tier! To build a service with these capabilities, we've designed a unique architecture using bare metal machines, a revolutionary millisecond cloud stack, and _unikernels_ (think: "hyper-specialized operating systems") running as ultra-lightweight microVMs. Thanks to the first-class integration of Prisma products, **Prisma Postgres comes with connection pooling, caching, and query optimization recommendations** out-of-the-box. Prisma Postgres is now available in Early Access 🎉
## A new era for "serverless" PostgreSQL Our new architecture takes a fundamentally different approach to provisioning databases compared to existing cloud providers and other serverless database products. In this section, we'll take a look at the trend of serverless databases and explain how Prisma Postgres fits into this category. Jump ahead to the [next section](##building-a-managed-postgresql-service-on-millisecond-cloud-infrastructure) if you care more about our architecture and technical details. ### What is a serverless database? Serverless databases (like AWS Aurora Serverless, Azure Cosmos DB, Neon, or Turso) follow a similar model to their counterparts in serverless compute: Their main promise is to free developers from managing database infrastructure while providing a cost-efficient "pay-as-you-go" pricing model. When using serverless databases, developers don't need to think about provisioning resources (like storage or compute), as the database auto-scales according to the application's needs. ### Cold starts: Major drawback of serverless databases The promise of auto-scaling often means that a database can scale down to zero, i.e., it's _suspended_. This can lead to high query latencies and poor user experience when the database needs to be "woken up" after inactivity, for example: Some database providers even require manual action from developers to wake a suspended database. While serverless databases have their advantages, cold starts are a major drawback! ### Serverless database providers can only offer very limited free tiers Free tiers are essential for developers to explore a database service, build hobby applications, and create proof-of-concepts. However, in recent years, offering free tiers has become a significant challenge for database providers. Due to technology designs that often rely on reselling infrastructure from major providers like AWS or require costly, resource-intensive container-based systems, these providers struggle to sustain viable free tiers. This difficulty has led companies like [PlanetScale](https://planetscale.com/blog/planetscale-forever) and [Heroku](https://help.heroku.com/RSBRUH58/removal-of-heroku-free-product-plans-faq) to discontinue their free tier offerings entirely. ### Prisma Postgres: A "serverless" database with a generous free tier & no cold starts What if you could get all the benefits of "serverless" without the drawbacks, like limited free tiers and cold starts? We are making this vision a reality by building a managed PostgreSQL service from the ground up. ![](https://cdn.sanity.io/images/p2zxqf70/production/f65bc24502ef9b28f0d5c7f3716e643015c62099-690x362.png?w=450) Today, we are thrilled to share the first step in this direction: We've teamed up with [Unikraft](https://unikraft.cloud/) to provision PostgreSQL instances using [Unikraft Cloud](https://unikraft.cloud/docs/), a groundbreaking millisecond cloud platform that eliminates cold starts, enables millisecond scale-to-zero and auto-scale, and allows for thousands of instances to run on a single bare metal machine.
Cold starts are a real pain. Unikraft Cloud provides cold starts in the order of a few milliseconds with hardware-level isolation.
This unique architecture not only eliminates cold starts but also offers superior economics by supporting thousands of databases on a single machine. This approach allows us to create a generous free tier that other database providers simply cannot afford. Read on to learn about the technical details of our new PostgreSQL service! ## Building a managed PostgreSQL service on millisecond cloud infrastructure Modern PostgreSQL providers typically rely on either of two approaches to provision database infrastructure: - Building on top of (essentially _reselling_) AWS infrastructure - Building a custom, container-based orchestration system (e.g., with Kubernetes) Prisma Postgres is neither. Instead, it uses Unikraft Cloud and is based on a new and unique architecture that delivers unmatched efficiency, safety (via strong, hardware-level isolation), speed, and developer experience when working with databases. ### An overview of the Unikraft Cloud stack Let's take a closer look at Unikraft Cloud's millisecond cloud infrastructure: To provide high efficiency and millisecond semantics, the Unikraft team had to optimize network components, cloud stack and application start time. Here's a quick overview of Unikraft Cloud's [core components](https://unikraft.cloud/how-it-works/) from the diagram above: - **Custom controller and proxy**: A custom platform controller that provides best-in-class, reactive, millisecond semantics and scalability. To make network processing fast, Unikraft Cloud couples this controller with a custom proxy which takes care of load-balancing and is able to very quickly react to incoming requests. - **Fast Virtual Machine Monitor (VMM) based on [Firecracker](https://firecracker-microvm.github.io/) and unikernels**: Unikraft Cloud's unikernels use lean images containing only the app, the code the app needs to run, and nothing more. Paired with a modified version of Firecracker VMM, these images start lightning fast. - **Snapshotting**: An optimized networking layer and cloud stack may not always be enough. Some applications can take seconds or minutes to initialize, potentially disrupting the platform's millisecond semantics. To address this, Unikraft Cloud offers optional snapshotting. It waits for the app to fully initialize, takes a memory snapshot, and then scales it to zero (with lots of engineering behind it, to ensure this works well at scale). Cold starts then resume from the snapshot, reducing them to milliseconds, even for large apps. ### No cloud provider: Prisma Postgres runs on bare metal We are building Prisma Postgres from first principles, striking the perfect balance between performance, cost, safety, and ease of use. To have _full_ control and avoid the limitations, constraints, and pricing models of major cloud providers, we chose to lease our own physical machines in data centers around the globe. Prisma Postgres is based on the observation that _modern hardware is incredibly powerful and cheap_ which was recently promoted by Basecamp:
Leaving the cloud will save us $7 million over five years.
In short: With Prisma Postgres, your database will run on powerful servers backed by high CPU core counts, large amounts of RAM, and super-fast NVME storage. ### Unikernels running as microVMs with Unikraft and Firecracker One of the core components of our architecture is the deployment of PostgreSQL inside _unikernels running as lightweight microVMs_. > Unikernels are famous for providing excellent performance in terms of boot times, throughput and memory consumption, to name a few metrics. > > [Unikraft: Fast, Specialized Unikernels the Easy Way](https://dl.acm.org/doi/abs/10.1145/3447786.3456248) (Research paper, EuroSys 21) Over the past few months, we've collaborated closely with the Unikraft team and have been deeply impressed by their work of increasing DX and making unikernels more approachable for developers. Our conclusion is clear: **Unikernels are finally ready to be adopted for high-performance production workloads.** Unikraft Cloud, which uses unikernels as one of its core components, provides the fastest, most economical, and safest way to deploy cloud-native applications: - **Fast**: Stateful scale-to-zero that resumes in single-digit milliseconds - **Economical**: No idle resource costs and superior server density for optimal economics - **Safe**: Hardware-level isolation for containers and functions Through an extra compilation step, Unikraft turns a traditional fullstack application container into a unikernel binary image that includes only the resources needed to run it — think: a _specialized operating system tailored to the needs of each particular application_: ### The Prisma Postgres unikernel binary is 5 times smaller than the original PostgreSQL image We've created the Prisma Postgres unikernel binary image in close collaboration with the Unikraft team. Here's the diagram of the Unikraft compilation process from before — but specialized for Prisma Postgres: The Unikraft team managed to trim the original PostgreSQL image down from 280MB to 61MB. Here's a breakdown of the components of the **Prisma Postgres image**: ![](https://cdn.sanity.io/images/p2zxqf70/production/c356d781c1816fad242fac28520fbe6199a9deae-2888x1858.png) We reduced the image to about 20% of its original size by identifying and removing unnecessary packages from our deployment. The original PostgreSQL image includes a lot of generic functionality that isn't needed for Prisma Postgres. In our architecture, these specialized binary images are deployed as unikernels on our bare metal machines; and, as unikernels are ultimately virtual machines, each PostgreSQL instance provides strong, hardware-level isolation. Thanks to unikraft, a single machine can host thousands of application (in our case: Prisma Postgres) instances: ![](https://cdn.sanity.io/images/p2zxqf70/production/90776da4721482b7372b74a8ace42afe009d86d2-1610x886.png) ### Comparing standard virtual machines, containers & unikernels Standard virtual machines (VMs), containers, and unikernels offer different approaches to creating [virtual environments](https://unikraft.org/docs/concepts/virtualization) on hardware. Unikernels take a first-principles approach to cloud deployment. In the cloud, arguably only two things matter: - the **hypervisor** for providing strong, hardware-level isolation (and so the virtual machines running on top of it) - your **application** Everything in between the two is overhead. A unikernel adds the thinnest possible layer of software between the two such that the application can run on the hypervisor with the highest efficiency: Here's a summary of the advantages unikernels have in comparison to standard VMs and containers: Unikraft's mission is to "enable developers to create a specialized OS for every single application to ensure the best performance, security guarantees, and desired KPIs." For us at Prisma, this means the machines with your PostgreSQL instances are _specialized_ for running PostgreSQL. This is in contrast to running PostgreSQL on a _general-purpose_ operating system, which consumes resources that are not relevant to the application (i.e., PostgreSQL). ### Why are there no cold starts with Prisma Postgres? Our architecture enables us to avoid cold starts while providing all the benefits of serverless products. This is achieved through the lightweight design of the individual components: - **Custom networking layer**: Unikraft Cloud's custom platform controller and custom proxy providing best-in-class, reactive, millisecond semantics and scalability. - **Pre-built unikernel images**: Our PostgreSQL unikernels are pre-built and optimized for rapid deployment. Each unikernel binary includes PostgreSQL and a minimal OS, avoiding lengthy and resource-heavy initialization processes. - **MicroVMs boot in milliseconds**: Unlike traditional virtual machines that take longer to initialise due to their larger overhead (BIOS, full OS, etc.), our microVMs are stripped of unnecessary components and can be launched in milliseconds. - **Multi-tier VM snapshotting:** Unikraft VMs combine the virtual machine monitor (VMM) of [Firecracker](https://firecracker-microvm.github.io/) with the packaging characteristics of unikernels. Firecracker makes it possible to create and restore VM memory snapshots, enabling a restore of a machine from hibernation in single-digit milliseconds. For Prisma Postgres, we are building a multi-tier snapshotting system that'll efficiently manage snapshots. This capability will allow us to hibernate databases after short durations of inactivity while still being capable of serving a request with negligible startup overhead. ## A fully integrated data layer with a DB, ORM, edge caching, connection pooling & more Prisma Postgres is a major step towards our vision of providing a fully integrated data layer for global applications. Our suite of Prisma products ensures you can [build, fortify, and grow](https://www.prisma.io/blog/bfg) data-driven applications without worrying about data modeling, migrations, querying, or complex and expensive infrastructure (like Redis or Apache Kafka): ![](https://cdn.sanity.io/images/p2zxqf70/production/ebc7c8fd2fb5b811ead970edee0ae69150f6e25c-2888x1858.png) Here's an overview of what you get with Prisma: - **Prisma Postgres**: A high-performance PostgreSQL instance that's always-on with pay-as-you-go pricing. - **Prisma ORM**: The [most popular ORM in the TypeScript ecosystem](https://www.prisma.io/blog/how-prisma-orm-became-the-most-downloaded-orm-for-node-js), featuring a human-readable schema, automated migrations, and intuitive, type-safe queries. - **Prisma Accelerate**: A connection pool and global caching layer that [drastically speeds up queries](https://accelerate-speed-test.prisma.io/) (with caching policies like TTL and SWR on a per-query level). - **Prisma Optimize**: An AI-driven [query analysis and recommendation system](https://www.prisma.io/data-platform/optimize?utm_source=docs) that helps you optimize your database queries. - **Prisma Studio**: The easiest way to [view and edit](https://www.prisma.io/docs/orm/tools/prisma-studio) your data visually. ## Get started with Prisma Postgres The fastest way to try Prisma Postgres is by following the instructions here:
After setting up the database, you will receive instructions for downloading and running a sample project. ### What you get with Prisma Postgres today Prisma Postgres is launching in Early Access today. During the Early Access phase, production use is not recommended and there are a few things to know: - There's a generous free tier that lets you get started, experiment with Prisma Postgres and build small projects with it 🎉 - Prisma Postgres always comes bundled with Accelerate, this means you get connection pooling and edge caching out-of-the box. - Prisma Postgres charges per query, for egress, and for storage/delivery of database events. You can find all details on our [pricing](https://www.prisma.io/pricing) page. Also check out the [documentation](https://www.prisma.io/docs/orm/overview/databases/prisma-postgres) to learn about current limitations of Prisma Postgres. ### Try Prisma Postgres Prisma Postgres offers fast boot times, low resource overhead, high security through isolation, and auto-scalability — all while being the PostgreSQL database you know and love. Today marks the initial release of Prisma Postgres. Look forward to the General Availability release early next year! We hope you're as excited as we are about this addition to the Prisma family. Try it out and let us know what you think on [X](https://x.com/prisma) and our [Discord](https://pris.ly/discord)!
> **Note**: Postgres, PostgreSQL and the Slonik Logo are trademarks or registered trademarks of the PostgreSQL Community Association of Canada, and used with their permission --- ## [Improving Query Performance with Indexes using Prisma: Hash Indexes](/blog/improving-query-performance-using-indexes-3-kduk351qv1) **Meta Description:** Learn how you can optimize a slow database query in your application with a Hash index using Prisma **Content:** ## Overview - [Introduction](#introduction) - [Hash tables: the data structure that powers hash indexes](#hash-tables-the-data-structure-that-powers-hash-indexes) - [When to use a hash index](#when-to-use-a-hash-index) - [Working with hash indexes using Prisma](#working-with-hash-indexes-using-prisma) - [Assumed knowledge](#assumed-knowledge) - [Development environment](#development-environment) - [Clone the repository and install dependencies](#clone-the-repository-and-install-dependencies) - [Project walkthrough](#project-walkthrough) - [Create and seed the database](#create-and-seed-the-database) - [Make an API request](#make-an-api-request) - [Improve query performance with a hash index](#improve-query-performance-with-a-hash-index) - [Summary and next steps](#summary-and-next-steps) ## Introduction In this part of the series, you will learn what hash indexes are, how they work, and when to use them, and then dive into a concrete example of how you can improve the performance of a query with a hash index using Prisma. If you want to learn more about the fundamentals of database indexes, check out the [first part](/improving-query-performance-using-indexes-1-zuLNZwBkuL). ## Hash tables: the data structure that powers hash indexes Hash indexes use the [hash table](https://en.wikipedia.org/wiki/Hash_table) data structure. Hash tables (also known as hash maps) are great data structures that allow fast data retrieval in almost _constant_ time (`O(1)`). This means the retrieval time of a record won't be affected by the size of the data being searched. > If you're unfamiliar with the concept of Big O notation, take a look at [What is Big O notation](https://jarednielsen.com/big-o-notation/). PostgreSQL's hash index is composed of "buckets" or "slots" into which [tuples](https://en.wikipedia.org/wiki/Tuple) are placed. ![](https://user-images.githubusercontent.com/33921841/194055764-a7c4adfd-b649-4597-af10-1676b0159272.png) PostgreSQL uses a _hash function_ to compute a _hash key_ or _hash code_ when storing a value to the index: - Hash key: maps the value to a 32-bit integer. - Hash code: maps to a bucket number in which the value will be stored. > **Hash function**: a function that maps data of arbitrary size to fixed-size values. > > **Hash code/ key**: the output of a hash function. When retrieving a record using a hash index, the database applies the hash function to the value to determine the bucket that might contain the value. After determining the bucket, the database will search through the tuple to find the records that match your query. ![](https://user-images.githubusercontent.com/33921841/194057994-bdf3aeca-85f8-4b06-801a-63bac39621be.png) If you're interested in reading about PostgreSQL's implementation of the hash index, you can read further [here](https://github.com/postgres/postgres/blob/master/src/backend/access/hash/README). ## When to use a hash index Hash indexes would be a solid choice if you only intend to use the equality operator (`=`) to query your data. For example, in the query in the example below, a hash index would be suitable. ```sql SELECT firstName from 'User' where lastName = 'Wick'; ``` If you intend to use range operators (`<`, `<=`,`>`, `>=`) when filtering your data, you can use a B-Tree index. You can refer to [part 2](/improving-query-performance-using-indexes-2-MyoiJNMFTsfq) to learn more about B-tree indexes. Hash indexes only work with the equality (`=`) operator. This means that a hash index would be a solid choice if you're using the `=` operator when querying your data. While a hash index might be a good choice for speeding up your queries, it comes with some caveats. Some of the limitations are that they: - Cannot be used to index multiple columns - Cannot be used to create sorted indexes - Cannot be used to enforce unique constraints ## Working with hash indexes using Prisma #### Assumed knowledge To follow along, the following knowledge will be assumed: - Some familiarity with JavaScript/TypeScript - Some experience working with REST APIs - A basic understanding of working with Git #### Development environment You will also be expected to have the following tools set up in your development environment: - [Node.js](https://nodejs.org/) - [Git](https://git-scm.com/downloads) - [Docker](https://www.docker.com/) or [PostgresQL](https://www.postgresql.org/download/) - [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) _(optional)_: intellisense and syntax highlighting for Prisma - [REST Client VS Code extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) _(optional)_: sending HTTP requests on VS Code > **Note**: If you don't have Docker or PostgreSQL installed, you can set up a free database on [Railway](http://railway.app/). ### Clone the repository and install dependencies Navigate to your directory of choice and clone the repository: ```bash copy git clone -b hash-indexes git@github.com:ruheni/prisma-indexes.git ``` Change the directory to the cloned repository and install dependencies: ```bash copy cd prisma-indexes npm install ``` Next, rename the `.env.example` file to `.env`. ```bash copy mv .env.example .env ``` ```cmd copy ren .env.example .env ``` ### Project walkthrough The sample project is a minimal REST API built with TypeScript and [Fastify](https://www.fastify.io/). The project contains the following file structure: ``` prisma-indexes ├── .github/workflows │ │ └── test.yaml │ └── renovate.json ├── node_modules ├── prisma │ ├── migrations/ │ ├── schema.prisma │ └── seed.ts ├── src │ └── index.ts ├── README.md ├── .env ├── .gitignore ├── docker-compose.yml ├── package-lock.json ├── package.json ├── requests.http └── tsconfig.json ``` The notable files and directories for this project are: - The `prisma` folder contains: - The `schema.prisma` file that defines the database schema - The `migrations` directory that contains the database migrations history - The `seed.ts` file that contains a script to seed your development database - The `src` directory: - The `index.ts` file defines a REST API using Fastify. It contains one endpoint called `/users` and accepts one optional query parameter — `firstName` - The `docker-compose.yml` file defining the PostgreSQL database docker image - The `.env` file containing your database connection string The application contains a single model in the Prisma schema called `User` with the following fields: ```prisma // prisma/schema.prisma model User { id Int @id @default(autoincrement()) firstName String lastName String email String } ``` The `src/index.ts` file contains _primitive_ [logging middleware](https://www.prisma.io/docs/concepts/components/prisma-client/middleware/logging-middleware) to measure the time taken by a Prisma query: ```typescript // src/index.ts prisma.$use(async (params, next) => { const before = Date.now() const result = await next(params) const after = Date.now() logger.info(`Query took ${after - before}ms`) return result }) ``` You can use the logged data to determine which Prisma queries are slow. You can use the logs to gauge queries that could require some performance improvements. `src/index.ts` also logs Prisma `query` events and parameters to the terminal. The `query` event and parameters contains the SQL query and parameters that Prisma executes against your database. ```typescript const prisma = new PrismaClient({ log: [{ emit: "event", level: "query", },], }) prisma.$on("query", async (e) => { logger.info(`Query: ${e.query}`) logger.info(`Params: ${e.params}`) }); ``` The SQL queries (with filled-in parameters) can be copied and prefixed with `EXPLAIN` to view the query plan the database will provide. ### Create and seed the database Start up the PostgreSQL database with docker: ```bash copy docker-compose up -d ``` Next, apply the existing database migration in `prisma/migrations`: ```bash copy npx prisma migrate dev ``` The above command will: 1. Create a new database called `users-db` (inferred from the connection string defined in the `.env` file) 1. Create a `User` table as defined by the model in `prisma/schema.prisma`. 1. Trigger the seeding script defined in `package.json`. The seeding step is triggered because it's run against a new database. The seed file in `prisma/seed.ts` will populate the database with a million user records. Start up the application server: ```bash copy npm run dev ``` ### Make an API request The cloned repository contains a `requests.http` file that contains sample requests to `http://localhost:3000/users` that can be used by the installed REST Client VS Code extension. The requests contain different `firstName` query parameters. > **Note**: Ensure you've installed the [REST Client VS Code extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) for this step. You can also use other API testing tools such as [Postman](https://www.postman.com/), [Insomnia](https://www.insomnia.rest/), or your preferred tool of choice.``` Click the **Send Request** button right above the request to make the request. ![](https://user-images.githubusercontent.com/33921841/184096935-1a680505-14fc-47ef-8862-126ef0d15708.png) VS Code will open an editor tab on the right side of the window with the responses. You should also see some information logged on the terminal. ![](https://user-images.githubusercontent.com/33921841/194079327-6dab2f11-a528-45f6-99f9-13db3a84cb0d.png) In the screenshot above, the query took 55 ms. ### Improve query performance with a hash index You can define a hash index in your Prisma schema file using the `@@index()` attribute function and providing the following arguments: - `fields`: a list of fields to be indexed - `type`: the name of the index created in the database The `@@index` attribute supports more arguments you can learn more about in the [Prisma Schema API Reference](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#index). Next, specify the `firstName` in the `fields` argument and `Hash` as the value of the `type` argument. ```prisma diff model User { id Int @id @default(autoincrement()) firstName String lastName String email String + @@index(fields: [firstName], type: Hash) } ``` After making the change, create and run another migration to create the index on the `firstName` field in the `User` model: ```bash copy npx prisma migrate dev --name add-firstName-index ``` ```sql --- prisma/migrations/[timestamp]_add_firstName_index/migration.sql -- CreateIndex CREATE INDEX "User_firstName_idx" ON "User" USING HASH ("firstName"); ``` Next, navigate to the `requests.http` file again and resend the requests to the `/users` route. You will notice an improvement in response times. In my case, in the screenshot below, the response times have been down to about 9 to 11ms. ![](https://user-images.githubusercontent.com/33921841/194080275-c4bd1059-595b-40b0-b2d9-b05339dac8cc.png) Congratulations! 🎉 You've learned how to reduce your database queries' response times using a hash index. ## Summary and next steps In this part, you learned what hash indexes are, their internal structure and limitations, and how to define and use a hash index using Prisma. If you would like learn about the fundamentals of database indexes and B-Tree indexes, refer to [part 1](/improving-query-performance-using-indexes-1-zuLNZwBkuL) and [part 2](/improving-query-performance-using-indexes-2-MyoiJNMFTsfq). In the following article, you will learn about GIN indexes: what it is, their structure, how it works, and how you can utilize a GIN index in your application using Prisma. --- ## [Studio for Prisma Postgres (Preview): View & Edit Your Data Online](/blog/studio-for-prisma-postgres-view-and-edit-your-data-online) **Meta Description:** Prisma Studio is now available in the Platform Console for Prisma Postgres databases. It’s the easiest way to explore and manipulate the data in your Prisma Postgres instance. **Content:** ## Prisma Studio: The easiest way to view and edit your data [Prisma Studio](https://www.prisma.io/studio) is a _database GUI_ that makes it easy to view and edit the data in your database. When using Prisma ORM, you can open it using the following command: ``` npx prisma studio ``` Traditional database GUIs can feel clunky and make the workflows for viewing and editing data more difficult than needed. Prisma Studio provides a _modern_ user interface that makes data accessible to a technical and non-technical audience alike. ![](https://cdn.sanity.io/images/p2zxqf70/production/785ef0347e31f513204bbc42d5af3a46984834ba-1080x266.png) Some key features of Prisma Studio are: - Perform **CRUD** operations on your data - View and modify **relations** between records - Add **filter** criteria to narrow down the list of records - **Sort and paginate** the list of records - **Hide columns** that are not relevant to your current goal ## Studio is coming to Platform Console for Prisma Postgres 🎉 Previously, Prisma Studio had only been available _locally_ when using Prisma ORM by running the `npx prisma studio` command. Now, Studio is available _online_ for your Prisma Postgres instances directly in [Console](https://console.prisma.io). > In case you’ve missed it: [Prisma Postgres](https://www.prisma.io/blog/announcing-prisma-postgres-early-access) is our new database offering! It is based on a unikernel architecture and has unique benefits like zero cold starts, a generous free tier, out-of-the-box connection pooling, caching, real-time events and more. It’s completely free while it’s running in Early Access — [try it out now!](https://www.prisma.io/docs/getting-started/quickstart-prismaPostgres) Simply navigate to the new **Studio** tab in the sidebar of your project environment and start exploring your data: ![](https://cdn.sanity.io/images/p2zxqf70/production/fe39b81e4a2a8ae7a983960b62edde68bdd82569-1965x1327.gif) ## Studio will soon be available for more databases If you’re not using Prisma Postgres, don’t sweat — Prisma Studio is coming to Console for other databases soon! In the meantime, let us know on [X](https://x.com/prisma) and [Discord](https://pris.ly/discord) what you think of Studio for Prisma Postgres and if there is anything else that you’d like to be able to do with it? We look forward to hearing from you! --- ## [How Poppy Uses Prisma Client to Ship Confidently](/blog/poppy-customer-success-story-swnWQcGRRvpd) **Meta Description:** Poppy offers rides of all kinds through its mobile app. Whether it's a car, scooter, or e-step, Poppy has it. Prisma plays a vital role in helping Poppy ship quickly and confidently and is a big reason they've just hit 1.5 million total rides taken. **Content:** ## Rides of All Kinds [Poppy](https://poppy.be/) is a mobility sharing service with huge value proposition: customers get a ton of choice over what kind of ride they want. Based in Belgium, Poppy offers over 500 shared cars, 400 e-scooters, and 200 e-steps in Antwerp, Brussels and now also Mechelen. All of these are available with a few taps in Poppy's mobile app. While Poppy's offering is straight-forward and their user experience smooth, the architecture that makes this possible is fairly complex. Not only does Poppy need to ship mobile apps that work on all devices, they also need to handle several complexities behind the scenes. Some of these include things like handling location awareness, payments, notifications, and more. Even with all these complexities, Poppy moves quickly on development and ships new features consistently. One key technology that has helped them achieve rapid development is **[Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client)**. ## Prisma at the Core [Thibaut Nguyen](https://www.linkedin.com/in/thibautnguyen/) is Poppy's CTO. A fan of GraphQL, he's been following along with Prisma's development since the early days. As Prisma matured to become the top choice for those wanting a type-safe database access client for Node.js, Thibault knew he wanted to use Prisma in his next greenfield project.
Two of us in the team were early graph.cool fans and were super impressed by the quality and developer experience. I remember checking Prisma 1 at the time but was a bit reluctant to add an additional server to set it up. Then when came the time to start on a greenfield project we gave Prisma 2’s early release a shot and were immediately convinced we had to use it as it integrated Typescript so well.
Today, all of Poppy's engineers are developing with Prisma and it is being used in production to serve thousands of rides per week. Poppy's tech stack is somewhat complex. This complexity is there behind the scenes to help ensure riders have a smooth experience. However, the tools that Prisma offers and, specifically, the great TypeScript experience provided by Prisma Client, have helped to reduce that complexity and have enabled Poppy's engineers to move quickly while being confident in their code. ![Poppy's tech stack](/blog/posts/poppy-diagram.png) Poppy's tech stack includes popular options across hosting, frameworks, and third-party services, including: - Node with Fastify - React Native - PostgreSQL - Redis - Twilio - Docker - Google Cloud Platform Poppy's service requires a large degree of location awareness. This is where some of the complexities in their stack arise. [PostGIS](https://postgis.net/) is an extension for PostgreSQL which gives geospatial capibilities to the database. Poppy uses PostGIS for geometry calculations and to do location-aware database queries. On top of this, Poppy collects IoT data from its vehicles in Google Big Query. This represents a large volume of data that needs to be managed. Type-safe database access through Prisma Client has been essential to help reduce coding errors for Poppy. This added layer of confidence when writing database access code has helped Poppy reduce overall complexity in their codebase and has enabled them to ship faster.
The combination of Prisma, TypeScript and our pretty thorough coverage with integration tests gives us the confidence to refactor critical parts of our code.
Type-safe database access through Prisma Client has been essential to help reduce coding errors for Poppy. This added layer of confidence when writing database access code has helped Poppy reduce overall complexity in their codebase and has enabled them to ship faster. ## Type-Safe Database Access for Fun and Profit Type safety is becoming ever more important for developers of all kinds. TypeScript's popularity has been skyrocketing and it's with good reason. The confidence developers get from working with type-safe code add enormous benefits to any organization. Type safety for database access is also becoming crucial. Instead of writing raw SQL with a lot of trial and error when querying a database, developers instead want to know exactly what they can and cannot do. With Prisma, developers get a type-safe database access client out-of-the-box. Database models are written with the Prisma Schema Language and TypeScript types are generated from it automatically. Databases modeled with Prisma are simple to read and write. ```prisma datasource db { url = env("DATABASE_URL") provider = "postgresql" } generator client { provider = "prisma-client-js" } model User { id Int @id @default(autoincrement()) email String @unique name String? posts Post[] } model Post { id Int @id @default(autoincrement()) title String @db.VarChar(255) author User? @relation(fields: [authorId], references: [id]) authorId Int? } ``` With a single command, the Prisma model provides a type-safe database access client. ```bash npx prisma generate ``` ```ts import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() async function getPosts() { return await prisma.post.findMany({ include: { author: true, }, }) } ``` ## Conclusion Prisma has been crucial for Poppy's success to date and the team anticipates it will continue to play a large role as the company grows. Type safety translates to confidence. Confidence at the database is especially important and, with Prisma Client, Poppy is able to achieve this. To find out more about how Prisma can help your teams boost productivity, join the [Prisma Slack community](https://slack.prisma.io/). --- ## [Building a REST API with NestJS and Prisma: Error Handling](/blog/nestjs-prisma-error-handling-7D056s1kOop2) **Meta Description:** In this tutorial, you will implement error handling in a NestJS application. You will learn two ways to handle errors: directly in your application code and by creating an exception filter. **Content:** ## Table Of Contents - [Introduction](#introduction) - [Development environment](#development-environment) - [Clone the repository](#clone-the-repository) - [Project structure and files](#project-structure-and-files) - [Detect and throw exceptions directly](#detect-and-throw-exceptions-directly) - [Handle exceptions by using exception filters](#handle-exceptions-by-using-exception-filters) - [Advantages of a dedicated exception layer](#advantages-of-a-dedicated-exception-layer) - [NestJS global exception filter](#nestjs-global-exception-filter) - [Create a manual exception filter](#create-a-manual-exception-filter) - [Apply the exception filter to your application](#apply-the-exception-filter-to-your-application) - [Bonus: Handle Prisma exceptions with the `nestjs-prisma` package](#bonus-handle-prisma-exceptions-with-the-nestjs-prisma-package) - [Summary and final remarks](#summary-and-final-remarks) ## Introduction In the [first chapter](/nestjs-prisma-rest-api-7D056s1BmOL0) of this series, you created a new NestJS project and integrated it with Prisma, PostgreSQL and Swagger. Then, you built a rudimentary REST API for the backend of a blog application. In the [second chapter](/nestjs-prisma-validation-7D056s1kOla1) you learnt how to do input validation and transformation. In this chapter you will learn how to handle errors in NestJS. You will look at two different strategies: 1. First, you will learn how to detect and throw errors directly in your application code inside the controllers of your API. 2. Next, you will learn how to use an [exception filter](https://docs.nestjs.com/exception-filters) to process unhandled exceptions throughout your application. In this tutorial, you will be using the REST API built in the [first chapter](/nestjs-prisma-rest-api-7D056s1BmOL0). You do not need to complete the [second chapter](/nestjs-prisma-validation-7D056s1kOla1) to follow this tutorial. ### Development environment To follow along with this tutorial, you will be expected to: - ... have [Node.js](https://nodejs.org) installed. - ... have [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/install/#compose-installation-scenarios) installed. If you are using Linux, please make sure your Docker version is 20.10.0 or higher. You can check your Docker version by running `docker version` in the terminal. - ... _optionally_ have the [Prisma VS Code Extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed. The Prisma VS Code extension adds some really nice IntelliSense and syntax highlighting for Prisma. - ... _optionally_ have access to a Unix shell (like the terminal/shell in Linux and macOS) to run the commands provided in this series. If you don't have a Unix shell (for example, you are on a Windows machine), you can still follow along, but the shell commands may need to be modified for your machine. ### Clone the repository The starting point for this tutorial is the ending of [part one](/nestjs-prisma-rest-api-7D056s1BmOL0) of this series. It contains a rudimentary REST API built with NestJS. The starting point for this tutorial is available in the [`end-rest-api-part-1`](https://github.com/prisma/blog-backend-rest-api-nestjs-prisma/tree/end-rest-api-part-1) branch of the [GitHub repository](https://github.com/prisma/blog-backend-rest-api-nestjs-prisma). To get started, clone the repository and checkout the `end-rest-api-part-1` branch: ```bash copy git clone -b end-rest-api-part-1 git@github.com:prisma/blog-backend-rest-api-nestjs-prisma.git ``` Now, perform the following actions to get started: 1. Navigate to the cloned directory: ```bash copy cd blog-backend-rest-api-nestjs-prisma ``` 2. Install dependencies: ```bash copy npm install ``` 3. Start the PostgreSQL database with Docker: ```bash copy docker-compose up -d ``` 4. Apply database migrations: ```bash copy npx prisma migrate dev ``` 5. Start the project: ```bash copy npm run start:dev ``` > **Note**: Step 4 will also generate Prisma Client and seed the database. Now, you should be able to access the API documentation at [`http://localhost:3000/api/`](http://localhost:3000/api/). ### Project structure and files The repository you cloned should have the following structure: ``` median ├── node_modules ├── prisma │ ├── migrations │ ├── schema.prisma │ └── seed.ts ├── src │ ├── app.controller.spec.ts │ ├── app.controller.ts │ ├── app.module.ts │ ├── app.service.ts │ ├── main.ts │ ├── articles │ └── prisma ├── test │   ├── app.e2e-spec.ts │   └── jest-e2e.json ├── README.md ├── .env ├── docker-compose.yml ├── nest-cli.json ├── package-lock.json ├── package.json ├── tsconfig.build.json └── tsconfig.json ``` The notable files and directories in this repository are: - The `src` directory contains the source code for the application. There are three modules: - The `app` module is situated in the root of the `src` directory and is the entry point of the application. It is responsible for starting the web server. - The `prisma` module contains Prisma Client, your interface to the database. - The `articles` module defines the endpoints for the `/articles` route and accompanying business logic. - The `prisma` module has the following: - The `schema.prisma` file defines the database schema. - The `migrations` directory contains the database migration history. - The `seed.ts` file contains a script to seed your development database with dummy data. - The `docker-compose.yml` file defines the Docker image for your PostgreSQL database. - The `.env` file contains the database connection string for your PostgreSQL database. > **Note**: For more information about these components, go through [part one](/nestjs-prisma-rest-api-7D056s1BmOL0) of this tutorial series. ## Detect and throw exceptions directly This section will teach you how to throw exceptions directly in your application code. You will address an issue in the `GET /articles/:id` endpoint. Currently, if you provide this endpoint with an `id` value that does not exist, it will return nothing with an HTTP `200` status instead of an error. For example, try making a `GET /articles/234235` request: ![Requesting an article that does not exist returns HTTP 200](/blog/posts/nestjs-error-handling/article-not-exist-200.png) To fix this, you have to change the `findOne` method in `articles.controller.ts`. If the article does not exist, you will throw a `NotFoundException`, a built-in exception provided by NestJS. Update the `findOne` method in `articles.controller.ts`: ```typescript copy // src/articles/articles.controller.ts import { Controller, Get, Post, Body, Patch, Param, Delete, + NotFoundException, } from '@nestjs/common'; @Get(':id') @ApiOkResponse({ type: ArticleEntity }) - findOne(@Param('id') id: string) { - return this.articlesService.findOne(+id); + async findOne(@Param('id') id: string) { + const article = await this.articlesService.findOne(+id); + if (!article) { + throw new NotFoundException(`Article with ${id} does not exist.`); + } + return article; } ``` If you make that same request again, you should get a user friendly error message: ![Requesting an article that does not exist returns HTTP 404](/blog/posts/nestjs-error-handling/article-not-exist-404.png) ## Handle exceptions by using exception filters ### Advantages of a dedicated exception layer You detected an error state in the previous section and manually threw an exception. In many cases, an exception will automatically be generated by your application code. In such cases, you should process the exception and return an appropriate HTTP error to the user. While it's possible to handle exceptions case by case in each controller manually, it is not a good idea for many reasons: - It will clutter your core application logic with a lot of error handling code. - Many of your endpoints will deal with similar errors, such as a resource not being found. You will have to duplicate the same error handling code in many places. - It would be hard to change your error handling logic since it is scattered across many locations. To solve these issues, NestJS has an [exception layer](https://docs.nestjs.com/exception-filters) which is responsible for processing unhandled exceptions across your application. In NestJS, you can create _exception filters_ that define how to handle different kinds of exceptions thrown inside your application. ### NestJS global exception filter NestJS has a global exception filter, which catches all unhandled exceptions. To understand the global exception filter, let's look at an example. Send _two_ requests to the `POST /articles` endpoints with the following body: ```json copy { "title": "Let’s build a REST API with NestJS and Prisma.", "description": "NestJS Series announcement.", "body": "NestJS is one of the hottest Node.js frameworks around. In this series, you will learn how to build a backend REST API with NestJS, Prisma, PostgreSQL and Swagger.", "published": true } ``` The first request will succeed, but the second request will fail because you already created an article with the same `title` field. You will get the following error: ```json copy { "statusCode": 500, "message": "Internal server error" } ``` If you take a look at the terminal window running your NestJS server, you should see the following error: ``` [Nest] 6803 - 12/06/2022, 3:25:40 PM ERROR [ExceptionsHandler] Invalid `this.prisma.article.create()` invocation in /Users/tasinishmam/my-code/median/src/articles/articles.service.ts:11:32 8 constructor(private prisma: PrismaService) {} 9 10 create(createArticleDto: CreateArticleDto) { → 11 return this.prisma.article.create( Unique constraint failed on the fields: (`title`) Error: Invalid `this.prisma.article.create()` invocation in /Users/tasinishmam/my-code/median/src/articles/articles.service.ts:11:32 8 constructor(private prisma: PrismaService) {} 9 10 create(createArticleDto: CreateArticleDto) { → 11 return this.prisma.article.create( Unique constraint failed on the fields: (`title`) ``` From the logs you can see that Prisma Client throws an unique constraint validation error because of the `title` field, which is marked as `@unique` in the Prisma schema. The exception is of type `PrismaClientKnownRequestError` and is exported at the Prisma namespace level. Since the `PrismaClientKnownRequestError` is not being handled directly by your application, it is automatically processed by the built-in global exception filter. This filter generates the HTTP `500` "Internal Server Error" response. ### Create a manual exception filter In this section, you will create a custom exception filter to handle the `PrismaClientKnownRequestError` that you saw. This filter will catch all exceptions of type `PrismaClientKnownRequestError` and return a clear user friendly error message to the user. Start by generating a filter class by using the Nest CLI: ```bash copy npx nest generate filter prisma-client-exception ``` This will create a new file `src/prisma-client-exception.filter.ts` with the following content: ```typescript // src/prisma-client-exception.filter.ts import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common'; @Catch() export class PrismaClientExceptionFilter implements ExceptionFilter { catch(exception: T, host: ArgumentsHost) {} } ``` > **Note**: There is a second file created called `src/prisma-client-exception.filter.spec.ts` for creating tests. You can ignore this file for now. You will get an error from `eslint` since the `catch` method is empty. Update the `catch` method implementation in `PrismaClientExceptionFilter` as follows: ```typescript copy // src/prisma-client-exception.filter.ts +import { ArgumentsHost, Catch } from '@nestjs/common'; +import { BaseExceptionFilter } from '@nestjs/core'; +import { Prisma } from '@prisma/client'; +@Catch(Prisma.PrismaClientKnownRequestError) // 1 +export class PrismaClientExceptionFilter extends BaseExceptionFilter { // 2 + catch(exception: Prisma.PrismaClientKnownRequestError, host: ArgumentsHost) { + console.error(exception.message); // 3 // default 500 error code + super.catch(exception, host); } } ``` Here you have made the following changes: 1. To ensure that this filter catches exceptions of type `PrismaClientKnownRequestError`, you added it to the `@Catch` decorator. 2. The exception filter extends the `BaseExceptionFilter` class from the NestJS core package. This class provides a default implementation for the `catch` method that returns an "Internal server error" response to the user. You can learn more about this [in the NestJS docs](https://docs.nestjs.com/exception-filters#inheritance). 3. You added a `console.error` statement to log the error message to the console. This is useful for debugging purposes. Prisma throws the `PrismaClientKnownRequestError` for many different kinds of errors. So you will need to figure out how to extract the error code from the `PrismaClientKnownRequestError` exception. The `PrismaClientKnownRequestError` exception has a `code` property that contains the error code. You can find the list of error codes in the [Prisma Error Message reference](https://www.prisma.io/docs/orm/reference/error-reference#prisma-client-query-engine). The error code you are looking for is `P2002`, which occurs for unique constraint violations. You will now update the `catch` method to throw an HTTP `409 Conflict` response in case of this error. You will also provide a custom error message to the user. Update your exception filter implementation like this: ```typescript copy //src/prisma-client-exception.filter.ts +import { ArgumentsHost, Catch, HttpStatus } from '@nestjs/common'; import { BaseExceptionFilter } from '@nestjs/core'; import { Prisma } from '@prisma/client'; +import { Response } from 'express'; @Catch(Prisma.PrismaClientKnownRequestError) export class PrismaClientExceptionFilter extends BaseExceptionFilter { catch(exception: Prisma.PrismaClientKnownRequestError, host: ArgumentsHost) { console.error(exception.message); + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const message = exception.message.replace(/\n/g, ''); + switch (exception.code) { + case 'P2002': { + const status = HttpStatus.CONFLICT; + response.status(status).json({ + statusCode: status, + message: message, + }); + break; + } + default: // default 500 error code super.catch(exception, host); + break; + } } } ``` Here you are accessing the underlying framework `Response` object and directly modifying the response. By default, [express](https://expressjs.com/) is the HTTP framework used by NestJS under the hood. For any exception code besides `P2002`, you are sending the default "Internal server error" response. > **Note**: For production applications, be careful to not leak any sensitive information to the user in the error message. ### Apply the exception filter to your application Now, for the `PrismaClientExceptionFilter` to come into effect, you need to apply it to a certain scope. An exception filter can be scoped to individual routes (method-scoped), entire controllers (controller-scoped) or across the entire application (global-scoped). Apply the exception filter to your entire application by updating the `main.ts` file: ```typescript copy // src/main.ts +import { HttpAdapterHost, NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; +import { PrismaClientExceptionFilter } from './prisma-client-exception.filter'; async function bootstrap() { const app = await NestFactory.create(AppModule); const config = new DocumentBuilder() .setTitle('Median') .setDescription('The Median API description') .setVersion('0.1') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api', app, document); + const { httpAdapter } = app.get(HttpAdapterHost); + app.useGlobalFilters(new PrismaClientExceptionFilter(httpAdapter)); await app.listen(3000); } bootstrap(); ``` Now, try making the same request to the `POST /articles` endpoint: ```json copy { "title": "Let’s build a REST API with NestJS and Prisma.", "description": "NestJS Series announcement.", "body": "NestJS is one of the hottest Node.js frameworks around. In this series, you will learn how to build a backend REST API with NestJS, Prisma, PostgreSQL and Swagger.", "published": true } ``` This time you will get a more user-friendly error message: ```json { "statusCode": 409, "message": "Invalid `this.prisma.article.create()` invocation in /Users/tasinishmam/my-code/median/src/articles/articles.service.ts:11:32 8 constructor(private prisma: PrismaService) {} 9 10 create(createArticleDto: CreateArticleDto) {→ 11 return this.prisma.article.create(Unique constraint failed on the fields: (`title`)" } ``` Since the `PrismaClientExceptionFilter` is a global filter, it can handle this particular type of error for all routes in your application. I recommend extending the exception filter implementation to handle other errors as well. For example, you can add a case to handle the `P2025` error code, which occurs when a record is not found in the database. You should return the status code `HttpStatus.NOT_FOUND` for this error. This would be useful for the `PATCH /articles/:id` and `DELETE /articles/:id` endpoints. ## Bonus: Handle Prisma exceptions with the `nestjs-prisma` package So far, you have learned different techniques for _manually_ handling Prisma exceptions in a NestJS application. There is a dedicated package for using Prisma with NestJS called [`nestjs-prisma`](https://github.com/notiz-dev/nestjs-prisma) that you can also use to handle Prisma exceptions. This package is an excellent option to consider because it removes a lot of boilerplate code. Instructions on installing and using the package are available in the [`nestjs-prisma` documentation](https://nestjs-prisma.dev/docs/installation/). When using this package, you will not need to manually create a separate `prisma` module and service, as this package will automatically make them for you. You can learn how to use the package to handle Prisma exceptions in the [Exception Filter](https://nestjs-prisma.dev/docs/exception-filter/) section of the documentation. In a future chapter of this tutorial, we will cover the `nestjs-prisma` package in more detail. ## Summary and final remarks Congratulations! You took an existing NestJS application in this tutorial and learned how to integrate error handling. You learned two different ways to handle errors: directly in your application code and by creating an exception filter. In this chapter you learned how to handle Prisma errors. But the techniques themselves are not limited to Prisma. You can use them to handle any type of error in your application. You can find the finished code for this tutorial in the [`end-error-handling-part-3`](https://github.com/prisma/blog-backend-rest-api-nestjs-prisma/tree/end-error-handling-part-3) branch of the [GitHub repository](https://github.com/prisma/blog-backend-rest-api-nestjs-prisma). Please feel free to raise an issue in the repository or submit a PR if you notice a problem. You can also reach out to me directly on [Twitter](https://twitter.com/tasinishmam). --- ## [Building on an Established Community: Prisma Now on Discord](/blog/announcing-discord-1LiAOpS7lxV9) **Meta Description:** Prisma is excited to expand the established Prisma Community Discord and further collaborate with the Prisma community. **Content:** Hello Prisma Community, We're excited to share an important update with you: Prisma is making an entrance onto [Discord](https://discord.gg/KQyTW2H5ca)! While we take great pride in our strong community of over 50,000 members on Slack, we believe it's time to extend our reach and foster additional collaborative conversations on Discord, a platform many of you already enjoy and have asked us to be present on. We are happy to oblige! You might already be aware of the unofficial Prisma community on Discord, a space that's been vibrant with discussions and brainstorming. We've seen the impressive engagement and support that this community has grown into and, after talks with the server's creator, we are excited to officially adopt and expand upon this community. We would like to express our deepest gratitude to the original server owner, [Olyno](https://github.com/Olyno), whose hard work and dedication have provided a strong foundation for our new community presence on Discord. Their passion has created a dynamic space where Prisma users could connect, share ideas, and support each other. We are thrilled to be able to carry on their work. So, why are we adopting Discord? Besides the fact that many of you asked us to set up a Discord server, we see Discord serving the Prisma community in several ways: ## Casual and open environment Discord's origins within the gaming community lends it a more relaxed atmosphere compared to the professional setting of Slack. This encourages informal and lively discussions, and allows users to interact more freely with our developer advocacy and support team. ## Powerful moderation tools Discord’s strong suite of community moderation tools help us ensure that our online environment remains respectful, friendly, and conducive to productive discussions. ## Topic-specific channels Discord’s multi-channel setup allows for more organized conversations on a variety of topics. Whether you want to talk about the latest updates, ask for help, or provide feedback, there's a channel just for that. ## Advanced integration capabilities From code repositories to social media feeds, Discord's integration capabilities provide a one-stop hub where our community can get all the latest news about Prisma. ## Real-time interaction With features like Stage Channels, we can host live events, AMAs, webinars, and more, encouraging real-time interaction between our team and the community. ![](/blog/posts/discord-announcement/discord-screenshot.png) We're incredibly excited to embark on this new chapter on Discord and look forward to enhancing the sense of camaraderie and collaboration that the Prisma community is known for. So whether you're an old member or a newcomer, we welcome you to join us on this exciting journey!
The Prisma Team --- ## [How Solin Uses Prisma Accelerate to Serve 2.5M Database Queries per Day](/blog/how-solin-uses-prisma-accelerate-to-serve-2-5m-database-queries-per) **Meta Description:** Learn how Prisma Accelerate has contributed to Solin's success by enhancing performance and reliability with its scalable connection pool and global database cache. **Content:** ## Solin brings the digital revolution to the fitness industry In the rapidly evolving fitness industry, staying ahead of the curve requires not just innovative ideas but also reliable and scalable technology solutions. [Solin](https://www.solin.stream/), a leading fitness marketplace for creators to sell programs, challenges, memberships, and cookbooks, has improved its platform by integrating [Prisma Accelerate](https://www.prisma.io/data-platform/accelerate). This story highlights how Prisma Accelerate has contributed to Solin's platform, enhancing performance and reliability, and why other businesses might benefit from this tool. ![](https://cdn.sanity.io/images/p2zxqf70/production/c808dbbce252a0914d4b1f13c09de462e9d077a1-2688x2050.png) [Solin](https://www.solin.stream/) connects fitness creators with consumers, offering a marketplace where creators can sell various fitness-related products and services, such as workout programs, challenges, and cookbooks. Consumers gain access to these offerings along with community features and transformation tracking, fostering a more interactive and hands-on digital fitness experience. ## The stack: Fullstack Remix + Prisma ORM Solin uses Remix as a *fullstack* framework for their application. They initially started out with a traditional Node.js API that was hosted on Heroku, but after a while, they decided to go all-in with Remix and switched to Vercel as their new hosting provider. They leverage Remix’ server-side capabilities and implement the entire API layer using serverless functions, which use Prisma ORM to query the database and are deployed via Vercel. Their PostgreSQL database is hosted on Heroku. ![](https://cdn.sanity.io/images/p2zxqf70/production/3057a791f5ec64f5eb6394e7b8c5193d8450a23e-2618x1237.png) ## Serving 2.5M database queries per day with Accelerate’s connection pool When accessing a database from serverless functions, it’s easy to exhaust the database connection limit and run out of connections during traffic spikes. This leads to failed requests and frustrated users. ![](https://cdn.sanity.io/images/p2zxqf70/production/542523ef4a619afc3ce8475550c08c8bbc6c8551-1850x678.png) For these situations, it’s crucial to add an external connection pool that can keep connections open and ensure their reuse. That’s why Solin decided to integrate Prisma Accelerate into their application stack! With its scalable connection pool and seamless integration with Prisma ORM, Prisma Accelerate is the perfect companion for building data-driven applications in a serverless environment. For Solin, this means they can easily keep up with the rapidly growing demand for their fitness platform, scaling it to thousands of users and serving more 2.5M database queries per day. Learn more about dealing with sudden traffic spikes in our recent post, [Saving Black Friday With Connection Pooling](https://www.prisma.io/blog/saving-black-friday-with-connection-pooling). ## Blazing fast response times thanks to database caching Prisma Accelerate not only offers a connection pool, but also comes with a global [cache](https://www.prisma.io/docs/accelerate/caching) that can be enabled on a per-query level. Because caching works especially well with content that rarely changes, Solin powers all of their landing pages with Prisma Accelerate. Thanks to the cache, Solin’s users get blazing fast response times when accessing their site. > "Accelerate is a perfect fit for landing pages. We are able to take advantage of caching to speed up queries and reduce latency, making them lightning fast. This obviously means we have a faster landing page, leading to better conversion." – Blake Carroll, CTO @ Solin Solin uses a combination of `swr` ([Stale-While-Revalidate](https://www.prisma.io/docs/accelerate/caching#stale-while-revalidate-swr)) and `ttl` ([Time-To-Live](https://www.prisma.io/docs/accelerate/caching#time-to-live-ttl)) options in their Prisma Client queries to control the caching behaviour on a query-level. Here is an example for how these options can be used: ```ts const myExpensiveQuery = await prisma.widget.findMany({ cacheStrategy: { ttl: 60 * 5, // serve from cache for 5 minutes swr: 60 * 2, // serve from cache for 2 more minutes and revalidate in the background }, }) ``` Fast responses are not the only benefit of integrating a database cache! It also notably reduces load on the database server, freeing up resources for more complex queries. The reduced load on the database server also shrinks the monetary cost for running it. ![](https://cdn.sanity.io/images/p2zxqf70/production/6eb1d966a877e30a33103ea5b451f09928de7ce1-2888x1110.png) ![](https://cdn.sanity.io/images/p2zxqf70/production/1abd3930cb6ad0701c2860ec6491495ea20858f4-2888x1110.png) Learn more about the benefits of caching in our recent article: [S](https://www.prisma.io/blog/saving-black-friday-with-connection-pooling)[peed and Savings: Caching Database Queries with Prisma Accelerate](https://www.prisma.io/blog/caching-database-queries-with-prisma-accelerate). ## At a glance: Solin’s benefits of using Prisma Accelerate To summarize, Solin benefits from using Prisma Accelerate in the following ways: - **Speed and efficiency**: Prisma Accelerate offers fast query performance, both for cached and non-cached queries. Quick data access and minimal latency are crucial for Solin. - **Reliability**: Since switching to Prisma Accelerate, Solin has not encountered connection issues, improving uptime, especially during peak usage times. - **Seamless integration and great DX**: The integration process with Prisma Accelerate was straightforward, allowing Solin to set it up and configure caching strategies with minimal effort. ## Try out Accelerate and speed up your database queries Convince yourself of the speed gains you can get with Prisma Accelerate by running the [Accelerate Speed Test](https://accelerate-speed-test.prisma.io/) or watch this 5min explainer video demoing how Accelerate improves query performance and application uptime: --- ## [How We Sped Up Serverless Cold Starts with Prisma by 9x](/blog/prisma-and-serverless-73hbgKnZ6t) **Meta Description:** Learn about the Prisma's goals, the hurdles we are overcoming, and how you can help. **Content:** ## Table of contents - [Enabling developers to reap the benefits of Serverless & Edge](#enabling-developers-to-reap-the-benefits-of-serverless--edge) - [The dreaded cold start 🥶](#the-dreaded-cold-start) - [They are inherently unavoidable](#they-are-inherently-unavoidable) - [They have a real-world impact](#they-have-a-real-world-impact) - [They are more complex than you might think](#they-are-more-complex-than-you-might-think) - [How Prisma contributes to a cold start](#how-prisma-contributes-to-a-cold-start) - [Improved startup performance by 9x](#improved-startup-performance-by-9x) - [A new JSON-based wire protocol](#a-new-json-based-wire-protocol) - [Host your function in the same region as your database](#host-your-function-in-the-same-region-as-your-database) - [Optimized internal schema building](#optimized-internal-schema-building) - [Various small wins](#various-small-wins) - [Aside: Findings about TLS](#aside-findings-about-tls) - [This is just the beginning](#this-is-just-the-beginning) - [You can help!](#you-can-help) ## Enabling developers to reap the benefits of Serverless & Edge At Prisma, we're huge believers in the premise of serverless and edge applications! These deployment paradigms have great benefits and allow developers to deploy their applications in more scalable and less costly ways. Serverless providers such as [Vercel](https://vercel.com/) (with Next.js API routes) or [AWS Lambda](https://aws.amazon.com/lambda/) are great examples of this. However, these paradigms also come with new challenges — especially when working with data! That's why in the past months, we've increased our focus on these deployment paradigms to help developers build data-driven applications while taking advantage and reaping the benefits of serverless and edge technologies. We are tackling this from two angles: - Building products that solve the new challenges that come with these ecosystems (such as [Accelerate](https://www.prisma.io/data-platform/accelerate), a globally distributed database cache) - Improving the experience with Prisma ORM in serverless and edge environments This article is about how we've improved one of the major issues developers face when building data-driven applications in serverless environments: _Cold starts_ when using Prisma ORM. ## The dreaded cold start 🥶 One of the most frequent performance issues when working in a serverless environment is long cold starts. _But what is a cold start?_ Unfortunately, this term carries a lot of ambiguity and is often misunderstood. Generally though, it describes _the time it takes for a serverless function's environment to be instantiated and its code to be executed_ when the function handles its first request. While this is the basic technical explanation, there are a few specific things to keep in mind about cold starts. ### They are inherently unavoidable A cold start is an unavoidable reality when working in a serverless environment. The primary "win" of serverless is that your application can scale up to infinity when traffic increases and down to zero when not in use. Without that capability, serverless would not be... serverless! If there are no requests for some time, all running environments are shut down — which is great because that also means you incur no costs. But it also means there are no functions left to instantly respond to incoming requests. They have to first be started again, which takes a little bit of time. ### They have a real-world impact Cold starts do not only have technical implications, but also create real-world problems for the businesses deploying serverless functions. Providing the best experience possible for your users is of the utmost importance and slow startup performance could steer users away. [Peer Richelsen](https://twitter.com/peer_rich) from [Cal.com](https://cal.com/) recently turned to Twitter after realizing their application was suffering from long cold starts: Ultimately, the goal of a developer working in a serverless environment should be to keep their cold start times as short as possible as long cold starts can result in bad experiences for their users. ### They are more complex than you might think Although the above explanation of cold starts is pretty straightforward, it is important to understand that different factors contribute to a cold start. We'll explain in the next couple of sections _what actually happens_ when a serverless function is first spawned and executed. > **Note**: Keep in mind, this is a general overview of how a serverless function is instantiated and invoked. The specific details of that process may vary depending on your cloud provider and configuration (we mostly use AWS Lambda as a reference). We are going to use this simple serverless function as an example to explain these steps: ```js let coldStart = true console.log("Outside: Executed when the application starts up!", { coldStart }) export const handler = async (event, context) => { console.log("Inside: Not executed when the application starts up.", { coldStart }) coldStart = false return { statusCode: 200, body: JSON.stringify({ hello: "world" }) } } ``` #### Step 1: Spinning up the environment When a function receives a request but no instances of it are currently available, your cloud provider initializes the execution environment where it will run your serverless function. Multiple steps happen during this phase: 1. The virtual environment is created with the CPU and memory resources you have allocated to your serverless function. 2. Your code is downloaded as an archive and extracted into the new environment's file system. (If you're using AWS Lambda, any associated [Lambda layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) are downloaded as well.) 3. The runtime (i.e. the language-specific environment your function runs in) is initialized. If your function is written in JavaScript, this will be the [Node.js runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html). Afterwards, the function is still not ready to process a request. The virtual environment is ready and all of the code is in place, but no code has been processed by the runtime yet. Before the handler can be invoked, the application must be initialized as described in the next step. > **Note**: These details of the startup of your function are not configurable and are handled by your cloud provider. You don't have much of a say in how this works. #### Step 2: Starting the application Generally, the application code exists in two different scopes: - Code _outside_ the handler function - Code _inside_ the handler function In this step, your cloud provider executes the code that is _outside_ the handler. The code _inside_ the handler will be executed in the next step. AWS Lambda logs the following when running the function from above: ``` 2023-04-21T13:27:20.986Z undefined INFO Outside: Executed when the application starts up! { coldStart: true } START RequestId: fedf6afa-ebcc-4335-82b9-2d341c316bdc Version: $LATEST ... ``` You can see how the outer `console.log("Executed when the application starts up!")` is executed even before the actual `START RequestId` is logged by AWS Lambda. If there were any imports, constructor calls or other code - that would also be executed at this time. (On a warm start request to your function, this line will not be logged any more at all. The code outside the handler is only executed once during a cold start.) #### Step 3: Executing application code In the final part of the startup process, the handler function is executed. It receives the incoming HTTP request (i.e. request headers, body, etc...) and runs the logic you have implemented. The AWS Lambda log from the previous step continues: ``` ... START RequestId: fedf6afa-ebcc-4335-82b9-2d341c316bdc Version: $LATEST 2023-04-21T13:27:20.991Z fedf6afa-ebcc-4335-82b9-2d341c316bdc INFO Inside: Not executed when the application starts up. { coldStart: true } END RequestId: fedf6afa-ebcc-4335-82b9-2d341c316bdc REPORT RequestId: fedf6afa-ebcc-4335-82b9-2d341c316bdc Duration: 2.84 ms Billed Duration: 3 ms Memory Size: 128 MB Max Memory Used: 67 MB Init Duration: 223.46 ms ``` With that, the cold start of your function has concluded and the execution environment is ready to handle further requests. > Aside: AWS Lambda logs the time it took to execute the code _inside_ the handler as `Duration`, which occurs in step 3. `Init Duration` is both the start of the environment and starting the application, so steps 1 and 2. ## How Prisma contributes to a cold start With that understanding of what a cold start is and the steps that are taken to initialize a serverless function, we will now take a look at where Prisma plays a role in that startup time. 1. Prisma Client is a Node.js module that is external to your function's code, and as such requires time and resources to be loaded into the execution environment's memory: The whole function archive needs to be downloaded from some storage, and then extracted into the file system. This is true for all Node.js modules, however it does add to the cold start and increases the more dependencies are used in a project - and Prisma can be one of those. 2. Once the code is loaded into memory, it also has to be imported into your handler's file and must be interpreted by the Node.js interpreter. For Prisma Client, that usually means calling `const { PrismaClient } = require('@prisma/client')`. 3. When Prisma Client is instantiated with `const prisma = new PrismaClient()`, the Prisma Query Engine has to be loaded and generates things such as input types and functions that allow the client to operate correctly. It uses the internal Schema Builder to do this. 4. Finally, once the virtual environment is ready to run your function's initial invocation, the handler will begin to execute your code. Any Prisma queries in that code, like `await prisma.user.findMany()`, will first initiate a connection to your database if one wasn't already opened by explicitly calling `await prisma.$connect()`, and then execute the query and return the data to your application. With this understanding, we can proceed to explain how we improved Prisma's impact on cold start. ## Improved startup performance by 9x Over the past couple of months, we increased our engineering efforts on addressing these cold start problems and are proud to say we have made magnificent strides 🎉 In general, we have been following the "Make it work, make it right, make it fast" philosophy while building Prisma ORM. After having launched Prisma ORM for production in 2020, adding support for multiple databases and implementing an extensive set of features, we're finally focusing on improving its performance. To illustrate our progress, consider the graphs below. The first one represents the cold start duration of an app with an comparatively large Prisma schema (with 500 models) before we began our efforts to improve it: This next graph is a peek at what the numbers currently look like after our recent efforts on performance enhancements: We won't sugar-coat the situation here, Prisma's startup time used to leave a lot to be desired and people have rightfully called us out for it. As you can see, we are now left with a _much_ shorter cold start though. The strides forward here came in the form of enhancements to our codebase, findings about how serverless functions behave and applying best practices. The next sections will describe these in more detail. ### A new JSON-based wire protocol The graph below is the same _before_ graph shown above: In this graph, the section of the **Prisma Client** bar represents the time spent running a `findMany` query during a function's initial invocation. That time is split into two chunks in the **Internals** bar: and . We quickly realized this graph did not make much sense. The majority of the time taken to run the query was spent... _not running the query_! This segment, which accounts for the majority of the `findMany` query segment, represents the time spent parsing what we call the DMMF (Data Model Meta Format), which is an internal structure used to validate queries that are sent to Prisma's [query engine](https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine#the-query-engine-file). The segment represents the time spent actually running the query. The root problem here was that Prisma Client used a GraphQL-like language as a wire protocol to communicate with the query engine. GraphQL comes with a set of limitations that forces the Prisma Client to use the DMMF (which can get in the ballpark of megabytes of JSON) to serialize queries. If you have been with Prisma for a long time, you might remember that Prisma 1 was a much more GraphQL-focused tool. When rebuilding Prisma as Prisma 2, fully focused on being a plain database ORM, we kept this part of our architecture without questioning it - and without measuring its performance impact. The solution we came up with was to redesign the wire protocol from the ground up in plain JSON, which makes the communication between Prisma Client and the query engine _a lot_ more efficient because it no longer requires the DMMF to serialize messages. After redesigning the wire protocol, we effectively removed the entire segment from the graph, leaving us with the following: > **Note**: You can check out pull requests [prisma-engines#3624](https://github.com/prisma/prisma-engines/pull/3624) and [prisma#17911](https://github.com/prisma/prisma/pull/17911) with the actual changes made if you are interested. Check out this amazing feedback on [GitHub](https://github.com/prisma/prisma/issues/18095) from users who tried out the new JSON-based wire protocol: > **Note**: The JSON-based wire protocol is currently in [Preview](https://www.prisma.io/docs/about/prisma/releases#preview). Once it's ready for production, it will become the default for how Prisma Client communicates with the query engine. Please give it a try and [submit any feedback](https://github.com/prisma/prisma/issues/18095) to help speed up the process of making this feature generally available. ### Host your function in the same region as your database After our switch to JSON protocol, the big distracting section was gone from the graph and we could focus on the remaining: We clearly noticed the and sections as the next big candidates. These represent the communication with the actual database that Prisma triggers. Anytime you host an application or function that needs access to a traditional relational database, you will need to initiate a connection to that database. This takes time and comes with latency. The same is true for any query you execute. The goal is to keep that time and latency to an absolute minimum. The best way to do this at the moment is to ensure your application or function is deployed in the _same_ geographical region as your database server. The shorter the distance your request has to travel to reach the database server, the faster that connection will be established. This is a very important thing to keep in mind when deploying serverless applications, as the negative impact that results from _not_ doing this can be significant. Not doing so can affect the time it takes to: - Complete a TLS handshake - Secure a connection with the database - Execute your queries All those factors are activated during a cold start, and hence contribute to the impact using a database with Prisma can have on your application's cold start. We, embarrasingly, noticed that we had done the first few runs of our tests with a serverless function at AWS Lambda in `eu-central-1`, and a RDS PostgreSQL instance hosted in `us-east-1`. We quickly fixed that, and the "after" measurement clearly shows the _tremendous_ impact this can have on your database latency, both for the creation of the connection, but also for any query that is executed: Using a database that is not as close as possible to your function will directly increase the duration of your cold start, but also incur the same cost any time a query will be executed later during handling of warm requests. ### Optimized internal schema building In the graph shown previously, you may have noticed that only two of the three segments on the **Internals** bar are directly related to the database. The other segment, "Schema builder", shown in , is not. This was an indicator to us that this segment was an area for potential improvement: The segment of the **Prisma Client** bar represents the time spent while Prisma Client runs its `$connect` function to establish a connection with the database. This segment is divided into two chunks in the **Internals** bar: and . The segment represents the time spent actually creating the database connection and the segment shows the time Prisma's query engine spends reading your Prisma schema, then using it to generate the schema it uses to validate incoming Prisma Client queries. The way those items were previously generated was not as optimized as they could have been. In order to shorten that segment, we tackled the performance issues we could find there. More specifically, we found ways to remove an expensive piece of code that transformed the internal Prisma Schema when the query engine was started before building the query schema. We also now [generate the strings for the name of many types in the query schema lazily](https://github.com/prisma/prisma-engines/pull/3775). That made a measurable difference. Along with that change, we also found ways to to optimize the code within the Schema Builder to improve memory layout, which lead to significant performance (run time) improvements. > **Note**: Check out the following example pull requests if you are interested in the specifics about the memory-allocation related fixes we made: > [#3828](https://github.com/prisma/prisma-engines/pull/3828), [#3823](https://github.com/prisma/prisma-engines/pull/3823) After applying these changes, the request from before looked like the following: Notice the segment is significantly shorter. This is a huge win, however there is still a segment there, which means time is being spent doing things that are not related to the database. We have already identified potential enhancements that will bring this segment near to (if not completely down to) zero. ### Various small wins Along the way, we also found many smaller inefficiencies that we were able to improve. There were a lot of these, so we won't go over each one, but a good example is an optimization we made to our platform detection routine used to search for the OpenSSL library on Linux environments (the pull request for that enhancement can be found [here](https://github.com/prisma/prisma/pull/18638)). This enhancement shaves ~10-20ms off the cold start on average. While that doesn't seem like much, the accumulation of this enhancement and other small enhancements we made add up to another good chunk of saved time. ## Aside: Findings about TLS Another finding we had during this initiative that is worth noting is that adding security to your database connection via TLS can have _a lot_ of impact on the cold start time _when your database is hosted in a different region than your serverless function_. A TLS handshake requires a round trip to and from your database. This is extremely fast when your database is hosted in the same region as your function, but can be very slow if they are far apart. Prisma Client enables TLS by default, as it is the more secure way to connect to your database. Because of this, some developers whose databases are not in the same region as their function may find an increased cold start time caused by that TLS handshake. The graph below shows the different cold start times with TLS enabled (first) and disabled (via [setting `sslmode=disable` in the connection string](https://www.prisma.io/docs/concepts/database-connectors/postgresql#arguments)): The TLS overhead shown above is negligible if your database is hosted in the same region as your function. Some other database clients and ORMs in the Node ecosystem disable TLS by default for PostgreSQL databases. When comparing the performance of Prisma ORM to them, this can unfortunately lead to performance impressions that are caused by this difference in out-of-the-box security. We recommend moving your database and functions into the same region rather than potentially compromising security to get a performance boost. This will keep your database secure and result in an even quicker cold start. ## This is just the beginning While we made incredible progress over the last couple of months, we're only just getting started. We want to: - Optimize the Schema Builder (the segment of the graphs) to be close to or actually 0 by potentially doing some of that work lazily or during query validation. - Optimize the loading of Prisma (the segment of the graphs), which represents the time it takes to load Prisma, as well and make it as small as possible. - Apply all of the above learnings to other databases besides PostgreSQL. - The big one: Look at the performance of Prisma Client _queries_ and optimize how long these take, both with little and a lot of data. You can expect updates to this blog post (when we further improve the cold start performance), or even another blog post in the coming weeks or months as we progress on our journey to improve Prisma ORM's performance. ## You can help! This goal to make the Prisma experience on serverless as smooth as we can is a very ambitious one. While we have a fantastic team dedicated to improving the startup performance of serverless functions using Prisma Client, we also realize we have a massive community of developers eager to contribute where they can to this initiative. We invite you to help improve the performance of Prisma Client, specifically in the context of serverless startup times. There are many ways you can contribute to this goal of providing a world-class ORM that is accessible in serverless environments and on the edge: - Submit [issues](https://github.com/prisma/prisma/issues) you find when working with Prisma on serverless. - Have an idea how we might improve? Start a [discussion](https://github.com/prisma/prisma/discussions)! - Try out the `jsonProtocol` preview feature and provide [feedback](https://github.com/prisma/prisma/issues/18095). Prisma ORM is an open source project, and as such we fully understand the importance of community feedback and participation. We love feedback, critiques, questions and anything that might help push Prisma forward for the good of every developer. --- ## [Try Prisma: The Fastest Way to Explore Prisma Examples](/blog/try-prisma-announcment-Kv6bwRcdjd) **Meta Description:** Announcing: Try Prisma. A CLI utility that allows you to easily set up and try out an example projects using Prisma. **Content:** ## Announcing `try-prisma` Here at Prisma, our goal is to make your lives as developers easier. Today, we are very excited to announce the release of our new tool that does just that: [`try-prisma`](https://github.com/prisma/try-prisma). For a while now, we at Prisma have maintained our [prisma-examples](https://github.com/prisma/prisma-examples) repository with up to date, ready-to-go projects using Prisma. The intent for these projects is to allow users to experience what Prisma would be like in their new stack while evaluating technologies. The process to set up one of these example projects, however, has been a very manual one, not providing the best developer experience we could provide. `try-prisma` fixes this by allowing you to run a single command to set up any example project you want to try! ## Embracing hands-on exploration As developers, we love to jump in and get our hands dirty when evaluating a new project or set of tools. With `try-prisma`, going from zero to experimentation is as simple as running a single command: ```shell copy npx try-prisma ``` The starter projects available typically include: - A fully configured and ready-to-go application in the selected stack - A detailed README with instructions on how to use the project - Prisma set up and configured with a starter schema - A seed script to populate your test database These projects allow you to skip the steps where you have to learn how all the little pieces of your stack work together, allowing you to jump right in and begin experimenting. ## The `prisma-examples` repository The `try-prisma` CLI tool gives you easy access to the projects available in the [prisma-examples](https://github.com/prisma/prisma-examples) repository. This repository contains an assortment of projects using different technologies that are organized into various folders based on the technolgies used. A few examples include: - [`javascript/graphql`](https://github.com/prisma/prisma-examples/tree/latest/javascript/graphql) - [`javascript/rest-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-nextjs) - [`typescript/rest-nestjs`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nestjs) - [`typescript/grpc`](https://github.com/prisma/prisma-examples/tree/latest/typescript/grpc) ## Built on your suggestions The [prisma-examples](https://github.com/prisma/prisma-examples) repository is a resource for the community that includes examples of various technologies in use with Prisma. ![](/blog/posts/try-prisma-announcement/suggestions.png) We love receiving feedback and encourage you to submit suggestions for new example projects or enhancements for existing projects. If you have any technologies you would like to see added to our library of examples or would like to submit a suggestion for an existing project, feel free to suggest it by clicking the respective link below:
Alternatively, you may submit a pull request to the [prisma-examples](https://github.com/prisma/prisma-examples) repository with your own example project or revisions following the [Contribution Guidelines](https://github.com/prisma/prisma-examples/blob/latest/CONTRIBUTING.md). These suggestions will be closely monitored and acted upon by the Developer Advocate team here at Prisma. ## Try it out! Sound exciting? Give it a try! To get started, head over to your terminal and run the following command: ```shell copy npx try-prisma ``` You will be walked through a series of questions about which project you would like to use, where it should be installed, and how it should be configured: ![](/blog/posts/try-prisma-announcement/process.gif) Open up the new project and head to the README for information on how to start experimenting! If you are curious about all of the options available via the CLI, head over to the `try-prisma` repository and check out the README.
If you run into any issues, feel free to leave an issue in the repository's [issues](https://github.com/prisma/try-prisma/issues) tab. We hope you'll give `try-prisma` a try and that it improves your experience when testing out new tools! --- ## [What's new in Prisma? (Q1/22)](/blog/wnip-q1-dsk0golh8v) **Meta Description:** Learn about everything that has happened in the Prisma ecosystem and community from January to March 2022. **Content:** ## Overview - [Releases & new features](#releases--new-features) - [MongoDB is now Generally Available](#mongodb-is-now-generally-available) - [Embedded documents support](#embedded-documents-support) - [Introspection of embedded documents](#introspection-of-embedded-documents) - [Index support for composite type fields](#index-support-for-composite-type-fields) - [Embedded document filters support](#embedded-document-filters-support) - [Ordering by embedded documents](#ordering-by-embedded-documents) - [Raw query support](#raw-query-support) - [Support for query logging](#support-for-query-logging) - [Filters no longer return `undefined` fields by default](#filters-no-longer-return-undefined-fields-by-default) - [New `isSet` filter operation](#new-isset-filter-operation) - [New `unset` operation](#new-unset-operation) - [New `updateMany` operation](#new-updatemany-operation) - [New `deleteMany` operation](#new-deletemany-operation) - [Many-to-Many relations require a reference argument](#many-to-many-relations-require-a-reference-argument) - [`@default(dbgenerated())` is now replaced with `@default(auto())`](#defaultdbgenerated-is-now-replaced-with-defaultauto) - [`@db.Array(ObjectId)` is now updated to `@db.ObjectId`](#dbarrayobjectid-is-now-updated-to-dbobjectid) - [Improved connection pooling resiliency](#improved-connection-pooling-resiliency) - [Prisma Client logger revamp](#prisma-client-logger-revamp) - [CockroachDB support is now in Preview](#cockroachdb-support-is-now-in-preview) - [Prisma Migrate improvements](#prisma-migrate-improvements) - [Trouble shooting migrations](#troubleshooting-migrations) - [Detecting state of a diff with `migrate diff` using an exit code](#detecting-state-of-a-diff-with-prisma-migrate-diff-using-an-exit-code) - [Full-text search for MySQL is now in Preview](#full-text-search-for-mysql-is-now-in-preview) - [`dataProxy` and `interactiveTransactions` Preview features are now mutually exclusive](#dataproxy-and-interactivetransactions-preview-features-are-now-mutually-exclusive) - [Interactive transactions concurrency](#interactive-transactions-concurrency) - [Community](#community) - [Meetups](#meetups) - [Videos, livestreams & more](#videos-livestreams--more) - [What's new in Prisma](#whats-new-in-prisma) - [Interviews](#interviews) - [Written content](#written-content) - [Prisma appearances](#prisma-appearances) - [We are hiring](#we-are-hiring) - [Stickers](#stickers) - [What's next?](#whats-next) ## Releases & new features Our engineers have been working hard, issuing new [releases](https://github.com/prisma/prisma/releases/) with many improvements and new features. This quarter, we adjusted our release cadence to every three weeks. Here is an overview of the most exciting features we've launched in the last three months. You can stay up-to-date about all upcoming features on our [roadmap](https://pris.ly/roadmap). ### MongoDB is now Generally Available This quarter was packed with lots of new features and improvements to the MongoDB connector, now Generally Available. MongoDB was launched in [Preview](https://www.prisma.io/docs/about/prisma/releases#preview) in July 2021 we've been working hard towards pushing it towards stability and polishing it to make it production-ready. Here are some of the feature highlights we developed over this period: - Expressive and type-safe operations for querying MongoDB **embedded documents** - Increased likelihood of **referential integrity** in your database - Thorough **introspection support** for using Prisma with existing MongoDB databases - **Declarative index management** right from your Prisma schema with `prisma db push` - Powerful **raw query APIs** to help you incrementally migrate to Prisma #### Embedded documents support In [`3.10.0`](https://github.com/prisma/prisma/releases/tag/3.10.0) we introduced support for reading and modifying embedded documents. Embedded documents provide access to a new `type` keyword in your Prisma schema you can use to define composite types. ```prisma model Product { id String @id @default(auto()) @map("_id") @db.ObjectId name String photos Photo[] } type Photo { height Int width Int url String } ``` Given the schema above, you can now read and write to the embedded `photos` array: ```ts // Create a new product with an embedded list of photos const product = await prisma.product.create({ data: { name: "Forest Runners", // Create an embedded list of photos in the product photos: [ { height: 100, width: 200, url: "1.jpg" }, { height: 300, width: 400, url: "2.jpg" }, ], }, }) ``` #### Introspection of embedded documents In `3.4.0`, we added preview support for the introspection of embedded documents. Running `prisma db pull` against your MongoDB database will generate `type` definitions within your Prisma schema. When introspecting your database, you can switch off the introspection of composite types with `--composite-type-depth=0` or limit the depth level of the analysis with, for example, `--composite-type-depth=2`. We took this further and updated the type inference behavior for embedded documents with mixed data types on introspection. From version [`3.11.0`](https://github.com/prisma/prisma/releases/tag/3.11.0), Prisma now defaults to a `Json` type for all fields that have mixed data types. Prisma will also show a warning on the console and add a comment to the introspected Prisma schema file to clarify where a field has a mixed data type. #### Index support for composite type fields In [`3.12.0`](https://github.com/prisma/prisma/releases/tag/3.12.0), we added support for adding indexes on embedded document fields in MongoDB. You can now define a normal, unique, or full-text index in your schema. ```prisma type Address { street String number Int } model User { id Int @id email String address Address @@index([email, address.number]) @@unique([email, address.street]) @@fulltext([email, address.street]) } ``` #### Embedded document filters support In `3.11.0`, we added the ability to filter embedded documents. Given the following schema: ```prisma model Product { id String @id @default(auto()) @map("_id") @db.ObjectId photos Photo[] } model Order { id String @id @default(auto()) @map("_id") @db.ObjectId shippingAddress Address billingAddress Address? } type Photo { height Int width Int url String } type Address { street String city String zip String } ``` You can now add filters within an embedded document: ```ts // find all orders with the same shipping address const orders = await prisma.order.findMany({ where: { shippingAddress: { equals: { street: "555 Candy Cane Lane", city: "Wonderland", zip: "52337", }, }, }, }) ``` You can also add a filter on a "contains many" relationship: ```ts // find all products that don't have photos const product = prisma.product.findMany({ where: { photos: { isEmpty: true } }, }) ``` This is just the tip of the iceberg of what's possible. To learn more, refer to our [documentation](https://www.prisma.io/docs/concepts/components/prisma-client/composite-types) for a complete list of available operations. #### Ordering by embedded documents In addition to embedded document filters, `3.11.0` added support for sorting by embedded documents. Using the schema from the previous example, you can sort orders by their zip code: ```ts // sort orders by zip code in ascending order const orders = await prisma.order.findMany({ orderBy: { shippingAddress: { zip: "asc", }, }, }) ``` #### Raw query support Raw queries in MongoDB help in writing queries Prisma doesn't support yet, such as: ```ts // To find zero or more documents matching a filter const result = await prisma.user.findRaw({ filter: { age: { $gt: 25 } }, options: { projection: { _id: false } }, }) // To perform aggregation operations on a collection await prisma.user.aggregateRaw({ pipeline: [ { $match: { status: 'registered' } }, { $group: { _id: '$country', total: { $sum: 1 } } }, ], }) // To run a command against the database await prisma.$runCommandRaw({ aggregate: 'User', pipeline: [ { $match: { name: 'Bob' } }, { $project: { email: true, _id: false } }, ], explain: false, }) ``` The raw query API for MongoDB differs from Prisma's `$queryRaw` SQL API to handle some low-level differences between databases to give you a better API and developer experience. #### Support for query logging You can enable query logging in Prisma Client when working with MongoDB from version `3.11.0`. ```ts const prisma = new PrismaClient({ log: [ { emit: 'event', level: 'query', }, ] }) prisma.$on('query', (e) => console.log(e.query)) ``` Prisma Client logs queries in the same format as the `mongosh` console. You can use the queries from your logs directly into your shell. #### Filters no longer return `undefined` fields by default In [`3.11.1`](https://github.com/prisma/prisma/releases/tag/3.11.1), we've changed the data returned when filtering MongoDB documents on `undefined` fields. The new rule is that `undefined` fields are excluded by default unless explicitly filtered for. This allows you to query for `undefined` and `null` values separately. For example, given the following Prisma schema: ```prisma model Address { id Int @id @map("_id") city String street String? // Note that street is optional } ``` For MongoDB, optional fields can either be `null` or `undefined` (absent). The following documents are all valid for the schema above: ```ts { "_id": 1, "city": "San Fransisco", "street": "Market st." } { "_id": 2, "city": "Seattle", "street": null } { "_id": 3, "city": "Chicago" } ``` Prior to `3.11.1`, if you queried for `where: { street: null }`, you'd get `_id: 2` and `_id: 3`. In `3.11.1`, you'll only get `_id: 2`. The ability to _also_ query for the missing fields has also been added. Refer to the new `isSet` below to learn more. There are a few exceptions to this new default: - A `having` filter on an aggregated field *will* return `undefined` fields. This is because aggregation on undefined fields yields `null`, not `undefined`, thus matching the filter. - Filters on undefined to-many relations (e.g., the backing array of a many-to-many is `undefined`) will currently include those relations in the result set. #### New `isSet` filter operation To compensate for missing fields on documents no longer being returned by the filters above, we’ve added a new `isSet: bool` filter. This filter can be used to include fields that are `undefined` on documents. The `isSet` operation has been added to all scalar and embedded fields that are optional. Using the example above, to include the `undefined` fields, you can use an `OR`: ```ts await prisma.address.findMany({ where: { OR: [ { street: { isSet: false } }, { street: null } ] } }) ``` #### New `unset` operation From `3.11.1`, you can also remove a field with the `unset` operation. Using the example above, let's write a query to remove the street field: ```ts // set the `street` field to `undefined` in the database await prisma.address.update({ where: { id: 10, }, data: { street: { unset: true, }, }, }) ``` #### New `updateMany` operation Prisma now supports updating embedded documents that match specific criteria. For example, given the following schema: ```prisma model Product { id Int @id @map("_id") name String @unique photos Photo[] } type Photo { height Int @default(200) width Int @default(100) url String } ``` You would then update photo with a `url` of `1.jpg` to `2.png`: ```ts const product = prisma.product.update({ where: { id: 10, }, data: { photos: { updateMany: { where: { url: '1.jpg', }, data: { url: '2.png', }, }, }, }, }) ``` #### New `deleteMany` operation Similar to `updateMany`, you can also remove embedded documents that match specific criteria. Using the Prisma schema from the previous example, you can delete all photos with a `height` of 100: ```ts const product = prisma.product.update({ where: { id: 10, }, data: { photos: { deleteMany: { where: { height: 100, }, }, }, }, }) ``` #### Many-to-Many relations require a reference argument From `3.10.0`, Prisma now enforces all the arguments in a MongoDB many-to-many relation. A `@relation` attribute must define `fields` and `references` argument to both sides. The `fields` argument must point to a scalar field in the same model and must be an array. The `references` argument must point to a scalar field in the opposite model, and it must be a singular type of the same base type as the referencing array on the other side. ```diff model Post { id String @id @map("_id") @default(auto()) @db.ObjectId category_ids String[] @db.ObjectId - categories Category[] @relation(fields: [category_ids]) + categories Category[] @relation(fields: [category_ids], references: [id]) } model Category { id String @id @map("_id") @default(auto()) @db.ObjectId post_ids String[] @db.ObjectId - posts Post[] @relation(fields: [post_ids]) + posts Post[] @relation(fields: [post_ids], references: [id]) } ``` #### `@default(dbgenerated())` is now replaced with `@default(auto())` The original purpose of dbgenerated is to support SQL expressions Prisma doesn’t understand yet. However, MongoDB doesn’t have a concept of default value expressions like SQL does. We took this opportunity to simplify how we handle the default values in MongoDB: ```diff model Post { - id String @id @default(dbgenerated()) @map("_id") @db.ObjectId + id String @id @default(auto()) @map("_id") @db.ObjectId } ``` #### `@db.Array(ObjectId)` is now updated to `@db.ObjectId` We've adjusted the Prisma schema format for scalar lists with native types (like lists of Object IDs). This will likely affect those with many-to-many relationships in MongoDB. We made this change to align MongoDB with our existing SQL databases better: ```diff model Post { id String @id @default(auto()) @map("_id") @db.ObjectId - categoryIDs String[] @db.Array(ObjectId) + categoryIDs String[] @db.ObjectId categories Category[] @relation(fields: [categoryIDs], references: [id]) } model Category { id String @id @default(auto()) @map("_id") @db.ObjectId - postIDs String[] @db.Array(ObjectId) + postIDs String[] @db.ObjectId posts Post[] @relation(fields: [postIDs], references: [id]) } ``` ### Improved connection pooling resiliency In [`3.12.0`](https://github.com/prisma/prisma/releases/tag/3.12.0), we busted a ghost that has been bugging teams since the early days of the Prisma ORM. Under certain amounts of load, some people reported that the connection pool would sometimes drop connections or deadlock and not recover. After many sightings and a lot of head-scratching, we could finally reproduce the issue. This allowed us to narrow down the problem to one of our dependencies and fix the problem. ### CockroachDB support is now in Preview [CockroachDB](https://www.cockroachlabs.com/) is a distributed SQL database that shines in its ability to scale efficiently while maintaining developer agility and reducing operational overhead. CockroachDB support is the product of collaboration with the Cockroach Labs team. You can use Prisma to introspect your existing database with `db pull` and evolve your schema and propagate changes to your database using Prisma Migrate. Please give it a spin and [let us know what you think](https://github.com/prisma/prisma/issues/11542) to help us iron out the kinks before we push it to General Availability. ### Prisma Client logger revamp We rewrote our internal logger in `3.11.0` to reduce [lock contention](https://en.wikipedia.org/wiki/Lock_(computer_science)#:~:text=lock%20contention%3A%20this%20occurs%20whenever,lock%20held%20by%20the%20other.) and enable future features like tracing. This is the first of many upcoming changes to improve Prisma Client's throughput. ### Prisma Migrate improvements #### Troubleshooting migrations We introduced 2 new CLI commands into Preview to improve the experience of troubleshooting migrations: - `prisma migrate diff` - `prisma db execute` Since we pushed Prisma Migrate for General Availability last year, we've gotten a ton of feedback to understand the challenges developers experience when building, testing, and deploying migrations. The `prisma migrate diff` command creates a diff of your database schema, Prisma schema file, or the migration history. You would have to feed the command with a `from` state and a `to` state to get a SQL script or human-readable diff in return. As a companion to the `prisma migrate diff`, we also built `prisma db execute` to execute SQL scripts against a database. You can pipe the output from `prisma migrate diff` directly to `prisma db execute --stdin`. Both commands are non-interactive, so it's possible to build many new workflows such as forward and backward migrations with some automation tooling. #### Detecting state of a diff with `prisma migrate diff` using an exit code We also introduced a new `--exit-code` flag to the `prisma migrate diff` command to detect the state of a diff in several ways. You can use the flag as follows: ```bash npx prisma migrate diff --preview-feature \ --exit-code \ --from-[...] \ --to-[...] ``` These are the default and changed behaviour of the error codes: ```bash ## Default behavior of exit codes 0: Returned when the diff is empty or non-empty 1: Returned on error ## Changed behavior when --exit-code is used 0: Returned when the diff is empty 1: Returned on error 2: Returned when the diff is non-empty ``` ### Full-text search for MySQL is now in Preview In `3.8.0` we added Preview support for full-text search in MySQL. You can enable full-text support by adding the `fullTextIndex` and `fullTextSearch` Preview flags in your Prisma schema and defining `@@fulltext()` indexes on fields you'd like to use full-text search on. ```prisma generator client { provider = "prisma-client-js" previewFeatures = ["fullTextIndex", "fullTextSearch"] } datasource db { provider = "mysql" url = env("DATABASE_URL") } model Post { id Int @id @default(autoincrement()) title String @unique @@fulltext([title]) } ``` Running `prisma db push` or `prisma migrate dev` will update your database schema, then running `prisma generate` will re-generate your Prisma Client, enabling you to use full-text search in your application. ```ts // search for titles that contain cat, but not fox await prisma.post.findMany({ where: { title: { search: "+cat -fox", }, }, }) ``` ### `dataProxy` and `interactiveTransactions` Preview features are now mutually exclusive Before `3.8.0`, Prisma `$transaction` queries would fail whenever the Data Proxy and Interactive Transactions Preview features were used together. The `interactiveTransactions` and `dataProxy` Preview flags cannot be used together in this release. Generating the Prisma Client when both Preview features are enabled will throw an error. ### Interactive transactions concurrency We fixed a [number of issues](https://github.com/prisma/prisma/issues/8707) in version `3.9.0` around timeouts and rollbacks when there were concurrent reads and writes. If you experienced timeouts or your interactive transactions weren't working quite as you expected, give it another go and let us know what you think. You can learn more about Interactive Transactions in our[ documentation](https://www.prisma.io/docs/concepts/components/prisma-client/transactions#interactive-transactions-in-preview). ## Community We wouldn't be where we are today without our amazing [community](https://www.prisma.io/community) of developers. Our [Slack](https://slack.prisma.io) has almost 50k members and is a great place to ask questions, share feedback and initiate discussions all around Prisma.
### Meetups ## Videos, livestreams & more ### What's new in Prisma Every other Thursday, [Nikolas Burk](https://twitter.com/nikolasburk), [Sabin Adams](https://twitter.com/sabinthedev), and [Alex Ruheni](https://twitter.com/ruheni_alex) discuss the latest Prisma release and other news from the Prisma ecosystem and community. If you want to travel back in time and learn about a past release, you can find all the shows from this quarter here: Some highlights of this quarter include the interviews with [A-J Roos about `prisma-redis-middleware`](https://youtu.be/TGMF8ykS29M?t=1437), [Michael Hayes about Pothos GraphQL](https://youtu.be/2dAtmHuT-30?t=870), [Peter Cilliers-Pistorius about seeding databases using Snaplet](https://youtu.be/OouLYZDveBU?t=1898) and [Cerbos Authorization with Alex Olivier](https://youtu.be/lqiGj02WVqo?t=3456). - [3.12.0](https://youtu.be/TGMF8ykS29M) - [3.11.0](https://youtu.be/2dAtmHuT-30) - [3.10.0](https://youtu.be/OouLYZDveBU) - [3.9.0](https://youtu.be/lqiGj02WVqo) ### Interviews We published several videos this quarter on our [YouTube channel](https://youtube.com/prismadata). Check them out and subscribe to not miss out on future videos. This quarter, we also recorded some interviews with Prisma employees: - [Nika Music](https://youtu.be/3SEjbascuj0) (Marketing Associate Intern) - [Alex Ruheni](https://youtu.be/31cdLSTcDbs) (Developer Advocate) We also published several videos showcasing how to work with Prisma and Planetscale: Be sure to subscribe to our YouTube channel to not miss any videos in the future:

### Written content During this quarter, we published several technical articles on the [Data Guide](https://www.prisma.io/dataguide) that you might find useful: - [Traditional databases vs serverless databases](https://www.prisma.io/dataguide/serverless/traditional-vs-serverless-databases) - [Introduction to provisioning MongoDB Atlas](https://www.prisma.io/dataguide/mongodb/mongodb-atlas-setup) - [Introduction to MongoDB indexes](https://www.prisma.io/dataguide/mongodb/mongodb-indexes) - [Introduction to MongoDB transactions](https://www.prisma.io/dataguide/mongodb/mongodb-transactions) - [How to create and delete users in MySQL](https://www.prisma.io/dataguide/mysql/short-guides/creating-deleting-users) - [How check your MySQL configuration for syntax errors](https://www.prisma.io/dataguide/mysql/short-guides/validate-configuration) - [Using `mysql_config_editor` to manage MySQL credentials](https://www.prisma.io/dataguide/mysql/tools/mysql-config-editor) - [Introduction to PostgreSQL connection URIs](https://www.prisma.io/dataguide/postgresql/short-guides/connection-uris) - [Identifying slow queries in MySQL](https://www.prisma.io/dataguide/mysql/reading-and-querying-data/identifying-slow-queries) - [Profiling and optimizing slow queries in MySQL](https://www.prisma.io/dataguide/mysql/reading-and-querying-data/optimizing-slow-queries) - [How to create and delete users in PostgreSQL](https://www.prisma.io/dataguide/postgresql/short-guides/creating-deleting-users) - [The United States' Most Popular Databases by state going into 2022](https://www.prisma.io/dataguide/just-for-fun/us-most-popular-databases-by-states) We also published several useful articles on our blog: - [Prisma Adds Support for MongoDB – Join Our Launch Week Celebrations](https://www.prisma.io/blog/mongodb-general-availability-pixnun6mffmu) - [Enabling static egress IPs in the Prisma Data Platform](https://www.prisma.io/blog/data-platform-static-ips) - [Improving Prisma Migrate DX with two new commands](https://www.prisma.io/blog/prisma-migrate-dx-primitives) - [Prisma support for CockroachDB is now in Preview](https://www.prisma.io/blog/prisma-preview-cockroach-db-release) - [Fullstack App with TypeScript, PostgreSQL, Next.js, Prisma and GraphQL: Image Upload](https://www.prisma.io/blog/fullstack-nextjs-graphql-prisma-4-1k1kc83x3v) - [Fullstack App with TypeScript, PostgreSQL, Next.js, Prisma and GraphQL: Authentication](https://www.prisma.io/blog/fullstack-nextjs-graphql-prisma-3-clxbrcqppv) ### Prisma appearances This quarter, several Prisma folks have appeared on external channels and livestreams. Here's an overview of all of them: - [Database Workflows & API Development with Prisma](https://youtu.be/cX5tEhv8Fjw) by [Nikolas Burk](https://twitter.com/nikolasburk) @CityJS Conf London and Node Congress - [Database Access on the Edge with Cloudflare Workers & Prisma](https://portal.gitnation.org/contents/database-access-on-the-edge-with-cloudflare-workers-and-prisma) by [Alex Ruheni](https://twitter.com/ruheni_alex) @Node Congress - Lightning Talk: What is Prisma by Alex Ruheni @ [ConfrontJs](https://confrontjs.com/) --- ## We are hiring Also, **we're hiring** for various roles! If you're interested in joining us, check out our [jobs page](https://www.prisma.io/careers).
--- ## Stickers We love seeing laptops decorated with Prisma stickers, so we're shipping them for free to our community members! In this quarter, **we've sent out over 500(!) sticker packs** to developers that are excited about Prisma!
--- ## What's next? [Prisma Day](https://www.prisma.io/day) is back this year, and it'll be on June 15 - 16 at the James&June Sommergarten in Berlin. Join us in-person or online for talks and workshops on modern application development and databases. If you'd like to share your project or give a talk, feel free to [submit a CFP](https://prisma-data.typeform.com/to/Gm9zMrKA). The best places to stay up-to-date about what we're currently working on are [GitHub issues](https://github.com/prisma/prisma/issues) and our public [roadmap](https://pris.ly/roadmap). You can also engage in conversations in our [Slack channel](https://slack.prisma.io), and start a discussion on [GitHub](https://github.com/prisma/prisma/discussions) or join one of the many [Prisma meetups](https://www.prisma.io/community) around the world. If you never want to miss any news from the Prisma community, [follow us on Twitter](https://twitter.com/prisma). --- ## [We Transitioned Prisma Accelerate to IPv6 Without Anyone Noticing](/blog/accelerate-ipv6-first) **Meta Description:** In July 2023, AWS announced the decision to begin charging for IPv4 addresses beginning in February 2024. This move had a major impact on Prisma Accelerate for reasons we’ll get into, prompting us to go all-in on IPv6. Join us for a deep dive into how we approached our IPv6 migration, lessons learned, and the outcome for users of Prisma Accelerate. **Content:** ## Prelude We should start with a bit of a primer on how Prisma Accelerate works. We’re overdue on a deep dive into Prisma Accelerate, so we’ll summarize the key architecture points. Prisma Accelerate is built on a hybrid cloud architecture spanning Cloudflare and AWS infrastructure. The caching, authorization, and request routing aspects of Prisma Accelerate occur at the edge using Cloudflare Workers. This leads to consistently fast cache hits for apps deployed all over the world. The edge is not so good for maintaining a connection pool and optimizing round-trips to a database that resides in a single region, so Prisma Accelerate operates an EC2 instance for each project in the AWS region closest to the database. We chose to completely isolate projects to their own EC2 instance for many reasons including security, performance, and workload isolation. These EC2 instances previously utilized an IPv4 network and were assigned a public IPv4 address to communicate externally. This setup was simple: a VPC in each of the 16 regions Prisma Accelerate supports and a subnet for each. Things get more interesting in how the EC2 instances are orchestrated, but we’ll save that for another post. The important takeaway is that Prisma Accelerate operates on thousands of EC2 instances that are provisioned and decommissioned as usage patterns change. An additional $3.60 per-month, per-instance, would have impacted our ability to provide a cost effective solution for our users. We needed to eliminate the public IPv4 addresses. ## IPv6 all the things Anyone looking at a transition to IPv6-only should know that IPv4 and IPv6 are different, incompatible protocols. A machine with only an IPv4 address cannot talk to an IPv6-only machine and vice-versa. It’s important to assess what external services your workload is communicating with and determine if those services advertise an IPv6 address. At first thought, it seemed like Prisma Accelerate would be suitable for a quick switch to IPv6. All incoming traffic routes through the Cloudflare Worker based edge network first, which advertises both IPv4 and IPv6 addresses for our users (thanks Cloudflare!). Communication from Cloudflare to AWS occurs within our internal network which supports both IPv4 and IPv6 as well. The challenge came in connecting to the user’s database. As it turns out, many popular database providers do not advertise IPv6 addresses. Over half of our Prisma Accelerate users relied on IPv4-only databases. This was unfortunate, as it meant that making Prisma Accelerate’s EC2 workload IPv6-only was not an option. Still, we needed to eliminate the new AWS levied cost of those IPv4 addresses. ## Enter DNS64 and NAT64 I’m a 90’s kid. I spent a substantial amount of time sitting in front of a CRT playing N64 🕹️ Unfortunately, that did not prepare me for DNS64/NAT64. Despite IPv4 and IPv6 being incompatible, it is possible to translate outgoing traffic from IPv6 to IPv4. A special IPv6 range, `64:ff9b::/96`, is designated for a protocol called [DNS64](https://www.rfc-editor.org/rfc/rfc6147.html). DNS64 encodes an IPv4 address into an IPv6 address. When an IPv6-only server executes a DNS query against a DNS64 name server, it will transform IPv4 `A` records into IPv6 `AAAA` records. The IPv6-only server will then send requests to the DNS64 IPv6 address. DNS64 alone only encodes and decodes the IPv4 address. Another host, usually a gateway, must be listening on the DNS64 IPv6 address to receive the request and proxy it to the destination IPv4. This process is called [NAT64](https://www.rfc-editor.org/rfc/rfc6146.html). The network routing configuration is configured to route the `64:ff9b::/96` range to the NAT64 gateway, so all IPv6-only hosts are unaware of the DNS64/NAT64 process. With NAT64 in place, only the NAT64 gateway needs a public IPv4 address to communicate with external IPv4-only servers. There was one case here that we did not catch early enough: explicit IPv4 addresses will not be encoded by DNS64 because they don’t go through DNS resolution. We have a small number of users on Prisma Accelerate that utilize direct IPv4 addresses in their connection strings. The initial rollout affected a few of these users. To mitigate this, we added some code to our orchestration workflow in Cloudflare Workers to detect an IPv4 and transform it with DNS64 before passing it to the EC2 instance. The DNS64 transformation is a simple function that is only a few lines of code to implement. ```tsx function applyDNS64(ipv4: string): string { // split the IPv4 address into octets // convert the octets in hexadecimal numbers const octets = ipv4 .split(".") .map((x) => parseInt(x)) .map((x) => x.toString(16).padStart(2, "0")); // construct the DNS64 IPv6 address // 64:ff9b::/96 is the well-known DNS64 prefix // your routing will need to send the 64:ff9b::/96 prefix to a NAT64 gateway return `[64:ff9b::${octets[0]}${octets[1]}:${octets[2]}${octets[3]}]`; } ``` ## IPv6-first Prisma Accelerate takes advantage of NAT64 in an approach we call IPv6-first. Every region Prisma Accelerate supports operates an AWS NAT gateway with NAT64 enabled. EC2 instances are placed into an IPv6-only VPC subnet, which automatically provisions a ***public*** IPv6 address from a specific address range and ***no*** IPv4 address. When the EC2 instance attempts to connect to a user’s database, it will prefer a direct connection over the public IPv6 address if the database also advertises an IPv6 address. Otherwise, a DNS64 address will be resolved instead, routing the request through the attached NAT gateway and to the database over IPv4. All internal traffic, including the request from Cloudflare to AWS, is always IPv6. Unfortunately, while this removes the IPv4 address cost, it does add additional data transfer costs over the NAT gateway. Prisma has decided to absorb this cost while the ecosystem adjusts to the new IPv6 landscape. We made this decision so that the transition is as seamless for our users as possible (you see now why we picked the title for this post? 😉). This decision is also in alignment with several of the developer experience focused principles that we’ve put across on our [Data DX manifesto](https://www.datadx.io/#manifesto). Using a NAT gateway in AWS comes with additional costs. For many workloads, it is more cost effective to utilize a dedicated IPv4 address rather than a NAT gateway. For others, like Prisma Accelerate, the NAT gateway is the more cost effective solution. We recommend doing your own analysis to identify the best solution for you. ## Unforeseen circumstances NAT64 solved our external networking challenges, which only exposed where we had unexpectedly relied on IPv4 internally. Prisma Accelerate runs processes on the EC2 instances that bind to ports for communication from Cloudflare to AWS. These bindings listened on IPv4 rather than IPv6. Fortunately, this was a simple change in our Cloudflare Workers based orchestration code which dynamically configures the EC2 instance. Prisma Accelerate orchestrates those processes on the EC2 instance using Docker. We observed container networking issues initially which were quickly resolved by enabling IPv6 on the local Docker network. Finally, everything was working, yet network calls appeared to be extremely slow. After some digging (yes, with `dig`), we identified that the slowness was caused by DNS resolution attempting to query an IPv4 address first, then using the correct IPv6 address. This was caused by our EC2 base AMI being created on an IPv4 network and restoring with that configuration. A few adjustments to DNS resolution and speeds looked great. ## Rollout Prisma Accelerate is so highly distributed that this change was deployed in a gradual way with no visible impact to users. We’re quite proud of this. 🏆 We began by deploying the new infrastructure to all regions. We manage infrastructure with [Pulumi](https://www.pulumi.com/) to ensure our configuration is repeatable in deployment and reviewable by our team. We mitigated infrastructure risk by deploying an all new VPC, subnet, NAT gateway,… everything, side-by-side with the existing infrastructure in every region. The new infrastructure was unused until we modified our orchestration code to deploy EC2 instances that utilized it. We conditionally toggled the new configuration by region, allowing us to gradually enable it and closely monitor the results. Beginning with our internal test region, we enabled the new configuration region-by-region from least utilized to most utilized. Enabling the new configuration in a region also didn’t have a dramatic impact though. Running EC2 instances are not immediately replaced by Prisma Accelerate. Rather, as instances were naturally recycled by the orchestration workflow, old IPv4-only instances were replaced with shiny, new, IPv6-first ones. This property of Prisma Accelerate was instrumental to our rollout as it minimized the risk and impact on active users. The initial rollout was very smooth across thousands of users. Yes, there were a few isolated issues (Murphy’s Law!). We built such an eventuality in our planning, enabling us to revert isolated regions with troubled users back to the previous version, deploy the fix and get the region back on IPv6 again. Over time, all user instances were replaced and we were able to decommission the old infrastructure. ## Outro Prisma Accelerate’s IPv6-first architecture optimizes for the future of the web while continuing to provide excellent support for IPv4-only databases. We’re actively working with our partners to improve the state of IPv6 adoption across the database ecosystem. Our team is excited to be on the forefront of innovation with Prisma Accelerate, and more exciting products to come. Today’s deep-dive was all about our switch from IPv4 to IPv6 on our internal network. In the next post, I’ll do a deep dive on the Prisma Accelerate architecture. We’ll explore how we saved money and increased uptime by migrating from Kubernetes to Cloudflare + EC2. Stay tuned or [sign up to get alerted](https://www.prisma.io/newsletter). --- ## [Speed and Savings: Caching Database Queries with Prisma Accelerate](/blog/caching-database-queries-with-prisma-accelerate) **Meta Description:** Achieve faster performance and cost savings with Prisma Accelerate's easy per-query caching, eliminating the need for maintaining caching infrastructure. Experience faster queries, without the hassle! **Content:** Picture this: You and your team just released your latest app, SuperWidget. Everyone is excited, and you’re pretty sure it’s going to be a hit… and it is! SuperWidget is all of a sudden used by every major company in the world. However, you quickly realize that the level of traffic far outweighs what you planned for and your app is starting to have degraded performance. To solve this, your team jumps into action quickly. You dive into your application monitoring and realize that several queries in your application have a much larger impact than anticipated. After a long night, your team implements a number of infrastructure improvements, most notably a robust caching layer, which takes the load off the rest of your infrastructure. SuperWidget performance is no longer being negatively impacted, and your new customers are happy with their experience. So, what could you and your team have done better? While your team was capable, fire drills and all-nighters are the last thing you want. The solution still required a coordinated effort and a lot of wasted engineering hours. Instead, you could have saved time and frustration by using [Prisma Accelerate](https://www.prisma.io/data-platform/accelerate?utm_source=website&utm_medium=blogpost&utm_campaign=caching) and caching your queries with ease. ### Why you should cache database queries As you saw in the above example, caching is great when you need to reduce database or application load. By caching, you can remove expensive operations from the time it takes to load your application, also known as the “critical path”. Following requests can then use this cached data to avoid spending app or database time computing the result. If improved stability due to reduced app load wasn’t enough, less time spent computing also means your infrastructure can support a higher workload, or your app can run on reduced hardware, saving you money! ![An image showing a large number of connections going from clients, to a server, to a database. The database is overloaded and stuck at 100% CPU. There is an X's for eyes emoji next to the database.](https://cdn.sanity.io/images/p2zxqf70/production/8b295baeeaf620323649d054718900fb542b6042-2888x1110.png) ![An image showing a large number of connections going from clients, to a server, through a cache, to a database. Thanks to the cache, the database is not overloaded. There is an emoji with sunglasses next to the database.](https://cdn.sanity.io/images/p2zxqf70/production/09cee9fb07d0f6190228e118596eed223a1ea99e-2888x1110.png) Another reason to cache would be to reduce egress costs. Many cloud providers charge egress costs for data leaving their services. This could be rows being served from your database, static images, even responses to or from other services. While faster load times and reduced costs are direct benefits of caching, they lead to another benefit: improved perception of your application! Quicker load times lead to a more enjoyable experience and [happier customers](https://www.prnewswire.com/news-releases/akamai-online-retail-performance-report-milliseconds-are-critical-300441498.html). Even if visitors are not paying you, an app that feels sluggish to load can lead to users spamming refresh at best and leaving for good at worst. When considering whether or not to cache a query, you should definitely keep these three reasons in mind, among others. Luckily, Prisma Accelerate can help: Accelerate features per-query caching with minimal egress costs. When using Prisma Accelerate, you can easily and quickly cache a problematic query: ```tsx const myExpensiveQuery = await prisma.widget.findMany({ cacheStrategy: { ttl: 60 * 5, // serve from cache for 5 minutes swr: 60 * 2, // serve from cache for 2 more minutes and revalidate in the background }, // [...] }) ``` In the first case, where expensive or frequently accessed queries can overwhelm your database, a per-query cache will prevent that load for as long as the data is cached. If cost is the concern, your data will be accessed from your database once and then cached in Accelerate’s collection of globally distributed nodes, preventing additional costs from further database reads while also making your app faster! ### When to cache Now that you know why and how to cache, you may be tempted to begin caching every query. Before you do that, note what happened in our example: you and your team monitored your application *before* implementing caching. Caching is great, but any addition can incur a cost or cause unintended side effects. At Prisma, we’re big fans of observability-driven development: instrument your app and make informed decisions. Caching should be a carefully considered option among many. If, for example, you need a certain query to always contain exactly up-to-date data, then caching will probably not be the right fit. On the other hand, cases where data doesn’t change often or doesn’t need to be up-to-date are great fits. This isn’t to say that you need to monitor production traffic before implementing any sort of caching. Caching can also be a helpful tool during the development process! If you have automated tests in your dev environment and you see a slow query, use Accelerate to quickly cache that query and measure results. If you see a noticeable improvement, maybe caching is a good fit. Regardless of the environment, the advice remains the same: measure and benchmark, make a change, and then measure again. > If you’re interested in query insights and diving deeper into optimizing performance, [check out Prisma Optimize](https://www.prisma.io/blog/prisma-optimize-early-access)! ### How Prisma Accelerate can help As you saw above, adding caching with Prisma Accelerate is as easy as adding a `cacheStrategy` option to a query. Since caching queries with Prisma Accelerate is on a **per-query basis**, you are only charged for the queries you _do_ cache. The rest of your application continues to run as-is. As soon as you determine that caching is necessary for a specific query, you can add it with just few lines of code! In addition to being able to quickly and easily implement caching, using Prisma Accelerate also means no need to set up additional caching infrastructure. While cloud providers have managed key-value stores, in the best case, you still need to manually insert data, manage indexes and replication, and be sure to invalidate when things change. With Prisma Accelerate, this is all handled for you! Add a cache strategy for the query you would like to cache and move on to building more great things. ![An image with two emoji. On the left is an emoji that looks dizzy and overwhelmed. Surrounding it are a lot of things that you have to think of when managing caching infrastructure: Redis, memcached, indexes, invalidation, in-memory, sharding, AWS, GCP. The emoji on the right is winking, clearly happy. It has two steps above it: 1. find a query to cache. 2. Use the Prisma Accelerate extension's `cacheStrategy` feature.](https://cdn.sanity.io/images/p2zxqf70/production/ff3f792f22982a08e1ebad1e81b0cc0d43c30b06-2888x1110.png) ### Is Prisma Accelerate right for me? When investigating any software, there are always a lot of options. We’ve found that Accelerate is a great fit for the following kinds of applications: - Static content, such as blog posts - Complex queries, such as usage calculation for billing related tasks - Read-heavy applications, such as social media platforms, news aggregators, and e-commerce sites Accelerate is also a great fit for teams that want to onboard engineers fast. Since Accelerate provides managed infrastructure and is built into Prisma Client, even new team members unfamiliar with your codebase can cache queries easily.
> Prisma Accelerate is more than just a cache! Accelerate is [edge distributed](https://accelerate-speed-test.prisma.io/) and also handles [connection pooling](https://www.prisma.io/docs/accelerate/connection-pooling). Be sure to check out [the full documentation](https://www.prisma.io/docs/accelerate/what-is-accelerate). > ### Wrapping up Caching is still one of the “hard” problems of software engineering and rightfully so! Simply caching more things won’t solve problems and a team needs to take the time to understand what can be cached and how it will impact their product. While there are many different approaches to caching, Prisma Accelerate makes it easy to implement caching on a pre-query basis and gives you more time to focus on building great products. If you’d like to take the next step, [learn more about Accelerate](https://www.prisma.io/data-platform/accelerate?utm_source=website&utm_medium=blogpost&utm_campaign=caching) and [get started](https://www.prisma.io/docs/accelerate/getting-started) caching your Prisma ORM queries today.

--- ## [Prisma Adds Support for MongoDB — Join Our Launch Week Celebrations 🎉](/blog/mongodb-general-availability-pixnun6mffmu) **Meta Description:** Prisma now supports MongoDB! Read this article to learn more about the benefits developers get when using MongoDB with Prisma and join our one-week celebration at the end of April. **Content:** ## Prisma + MongoDB = 💚 Support for [MongoDB](https://www.mongodb.com/) has been one of the [most requested features](https://github.com/prisma/prisma/issues/1277) since the initial release of the Prisma ORM. Using both technologies together makes developers more productive and allows them to ship more ambitious software faster. ![](/blog/posts/mongodb-ga/issue.png) ### No more data inconsistencies thanks to the Prisma schema Node.js developers love MongoDB for the flexibility it provides and a familiar JSON-based data model! However, being a _schemaless_ database means that MongoDB users can easily run into data inconsistencies as their projects start to evolve and grow in size. With Prisma, developers can easily define a _schema_ for the data that they want to store in MongoDB. This has several benefits: - The data structures inside of MongoDB become explicit. - The consistency of the data stored in MongoDB is ensured by Prisma. - All team members are aware of the data stored inside of MongoDB. Prisma schemas are written in Prisma's intuitive and human-readable modeling language, here's what an example looks like: ```prisma model User { id String @id @default(auto()) @map("_id") @db.ObjectId createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String? @unique posts Post[] profile Profile? } model Post { id String @id @default(auto()) @map("_id") @db.ObjectId title String content String? published Boolean @default(false) author User @relation(references: [id], fields: [authorId], onDelete: Cascade) authorId String @db.ObjectId } type Profile { firstName String lastName String profilePicture String? department Department? } enum Department { Marketing Sales Engineering } ``` Prisma's data model makes it particularly easy to work with _relations_. In the schema example above, you see a one-to-many relation from `User` to `Post` via a [_reference_](https://www.mongodb.com/docs/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/) as well as the `Profile` type which represent an [_embedded document_](https://www.mongodb.com/docs/manual/tutorial/model-embedded-one-to-one-relationships-between-documents/) on the `User` model. ### Auto-completing database queries Similar to MongoDB, Prisma also provides a database client that you can use to query your MongoDB database: Prisma Client. One of the main differences between the two is that Prisma Client is _aware_ of the schema you define, so it can help you write your queries via auto-completion. ![](/blog/posts/mongodb-ga/autocomplete.gif) Prisma also allows you to fall back to MongoDB's native query API when you need to run more specialized queries against your MongoDB instance. ### Cascading deletes/updates on reference-based relations MongoDB doesn't natively support _referential actions_ (i.e. cascading deletes/updates). Prisma "polyfills" this functionality and allows developers to configure these in the Prisma schema and can therefore can contribute to the [referential integrity](https://en.wikipedia.org/wiki/Referential_integrity) of the data in your MongoDB database. In the data model above, the `@relation` attribute on the `author` field uses `onDelete: Cascade`. This means that when a `User` document is deleted, all the `Post` documents that were related to it are deleted as well. ### Prisma makes MongoDB type-safe Prisma especially starts to shine when it's used in a TypeScript application as it provides extremely strong type-safety guarantees. For example, consider this query where we specify via the `select` option which fields of the `User` model (and its relations) should be returned in the response: ```ts const userData = await prisma.user.findFirst({ select: { id: true, email: true, profile: { select: { firstName: true, lastName: true } }, posts: { select: { title: true } } } }) ``` ```ts const userData: { id: string; email: string | null; profile: { firstName: string; lastName: string; } | null; posts: { title: string; }[]; } | null ``` If you select the **Generated Type** tab in the code snippet above, you see that the type of the resulting `userData` constant is now tailored to the fields that are selected in the query. This has two main benefits: - The TypeScript compiler will catch cases where you accidentally access a field that was not returned from the query. ![](/blog/posts/mongodb-ga/compiler-error.png) - Your auto-completion suggestions are tailored to the given type. ![](/blog/posts/mongodb-ga/autocomplete.png) ## Try out MongoDB with Prisma today We are excited to see what you're going to build with MongoDB and Prisma! You can get started with MongoDB in our documentation (see buttons below). ### Get started from scratch ... To get started with MongoDB and Prisma, you can follow our guide to set up a new project from scratch.
### ... or use Prisma with your existing MongoDB database If you already have an existing project that uses a MongoDB database, you can easily start to incrementally adopt Prisma. Prisma has an _introspection_ features that reads the structures of the documents you have stored in your MongoDB collections and creates according Prisma models. We are also going to publish a migration guide from Mongoose [soon](https://github.com/prisma/docs/issues/2793).
## Join us for a week of celebrations 🎉 To celebrate MongoDB support in Prisma, we are planning a launch week at the end of April with lots of fun activities, new content and awesome events! - Date: **April 25 - 29** - Location: **Virtual** - Website: [**https://www.prisma.io/mongodb-launch**](https://www.prisma.io/mongodb?utm_source=website&utm_medium=blogpost&utm_campaign=mongodblaunch) Sign up via the website above to join us for the launch week! You can also [**submit a talk proposal for our Showcase Lightning Talks (~3min)**](https://prisma-data.typeform.com/to/GvDz1Tzz) if you are building something with MongoDB and Prisma and want to talk about it during the launch week! ![](/blog/posts/mongodb-ga/launchweek.png) --- ## [Cloudflare, Unikernels & Bare Metal: Life of a Prisma Postgres Query](/blog/cloudflare-unikernels-and-bare-metal-life-of-a-prisma-postgres-query) **Meta Description:** Take a look under the hood of the most innovative PostgreSQL database on the market and learn how a query travels through Cloudflare, unikernels and bare metal. **Content:** ## Recap: What is Prisma Postgres? In case you haven't heard: [**Prisma Postgres is the first database built on unikernels**](https://www.prisma.io/blog/announcing-prisma-postgres-early-access). Here's a quick 100-second summary if you missed it: ### Built on next-generation infrastructure Prisma Postgres is not just another AWS wrapper! Its architecture has been carefully designed from first principles and builds on next-generation infrastructure like [unikernels](https://en.wikipedia.org/wiki/Unikernel), [Unikraft Cloud](https://unikraft.cloud/) and [Cloudflare Workers](https://workers.cloudflare.com/). The combination of these technologies provides unique benefits and a powerful feature set. ### No cold starts, global caching, connection pooling & more Here's what developers get when using Prisma Postgres as their serverless database: - **Zero cold starts**: Instant access to your database without delays. - **Generous free tier**: 100k operations, 1GiB storage per month & 10 databases. - **Global caching layer**: Query responses are easily cached at the edge. - **Built-in connection pool**: Scale your app without worrying about TCP connections. - **Performance tips**: AI-powered recommendations for speeding up your queries. - **Simple pay-as-you-go pricing**: Predictable costs based on operations & storage.
## Life of a Prisma Postgres query With our short recap out of the way, let's dive into the tech stack Prisma Postgres uses to enable these benefits. Spoiler: Here's the full overview of all components involved in the lifecycle of a Prisma Postgres query: ![Prisma Postgres components](https://cdn.sanity.io/images/p2zxqf70/production/b38aa9235dab3c4bbef178b0944da6f97a9c2c2f-660x852.png) In the next sections, we'll take a closer look at each stage and explain what's going on under the covers. ### Stage 1: It all starts with Prisma ORM [Prisma ORM](https://www.prisma.io/orm) is where the journey of a Prisma Postgres query naturally starts. #### No query engine needed on the application server with Prisma Postgres If you've used Prisma ORM in the past, you may be aware that it uses a _Query Engine_ that's implemented in Rust and which runs as a binary on your application server. > Note that while we're still talking about the Query Engine being written in Rust in this context, it is currently being rewritten in TypeScript. Learn more [here](https://t.co/JJnKm2Fs7y). The core responsibilities of the Query Engine are: - Generating an efficient SQL query based on the high-level ORM query (written in JS/TS) - Managing the database connection pool The neat thing about using Prisma ORM with Prisma Postgres though is that you don't need the Query Engine running on your application server. Instead, you'll use a super lightweight version of Prisma ORM _without_ the Query Engine. The heavy-lifting of generating SQL queries and managing TCP connections is pushed down further in the stack into the connection pool that sits on top of Prisma Postgres. This approach of hosting the connection pool on the Prisma Postgres infrastructure has major benefits: Freeing application developers from managing the connection pool lets them focus on their data needs and queries. It is also especially useful in short-lived environments, like serverless and edge functions, where re-creating the connection pool again and again causes a major performance overhead. #### Defining a Prisma ORM query with a cache strategy Let's use the following Prisma ORM query for the purpose of this article: ```ts const users = await prisma.post.findMany({ where: { published: true }, cacheStrategy: { ttl: 60, swr: 30, } }) ``` This query fetches all published posts from the database and additionally specifies two parameters that will be relevant for the Prisma Postgres cache: - [Time-To-Live](https://www.prisma.io/docs/accelerate/caching#time-to-live-ttl) (`ttl`): Determines how long cached data is considered _fresh_. When you set a TTL value, Prisma Postgres will serve the cached data for that duration without querying the database. - [Stale-While-Revalidate](https://www.prisma.io/docs/accelerate/caching#stale-while-revalidate-swr) (`swr`): Allows Prisma Postgres to serve _stale_ cached data while fetching fresh data in the background. When you set an SWR value, Prisma Postgres will continue to serve the cached data for that duration, even if it's past the TTL, while simultaneously updating the cache with new data from the database. In this example, the data will be considered fresh for 30 seconds (TTL). After that, for the next 60 seconds (SWR), Prisma Postgres's cache will serve the stale data while fetching fresh data in the background. Prisma Postgres serves cached data from an edge location close to your application. If you deploy your app to multiple locations, this global cache can dramatically improve the performance of your app! #### Executing the query via HTTP So, when the query above is executed in an application, what happens next? Because the Query Engine has been pushed down the stack, all that happens at this stage is an HTTP request to the first auth and routing layers of Prisma Postgres' infrastructure. This HTTP request carries a lightweight, JSON-based representation of the query. Here is what it looks like: ```json { "modelName": "Post", "action": "findMany", "query": { "arguments": { "where": { "published": true } }, "selection": { "$scalars": true } } } ``` Note that the `selection` argument specifies the fields that should be fetched from the database. Since we didn't use a `select` or `include` option on our query, its value simply is `"$scalars": true` which means that all scalar fields of the target model will be return from the database. The next step for the request to be evaluated by Prisma Postgres' authentication and cache layers. ### Stage 2: Authenticating the request Before hitting the cache to check if the query result can be served from there, the query needs to be authenticated. A Prisma Postgres URL always contains an `apiKey` argument that encodes the user credentials: ``` prisma+postgres://accelerate.prisma-data.net/?api_key=ey... ``` The auth layer is implemented using Cloudflare Workers, and therefore in close physical proximity to the origin of the query. It uses the `apiKey` value to identify the user, validate the access permissions and route the request to the next stage. ### Stage 3: To cache or not to cache After authentication, the HTTP request is going to hit the next layer of the Prisma Postgres infrastructure which is implemented via Cloudflare Workers as well: The main purpose of this routing layer is to determine whether the Prisma Postgres cache needs to be activated: - If the query has `swr` and/or `ttl` options set, the query will enter the path to the Prisma Postgres cache. - If the query doesn't have either of these caching options, it will directly move to the next stage. So, let's investigate the path through Prisma Postgres' caching layer. Being built on top of Cloudflare Workers, the Prisma Postgres cache takes advantage of the official [Cloudflare Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/). As a cache key, it uses a hash that's computed based on the _entire_ Prisma ORM query (including values for the query parameters, such as `published: true` in the case above). This approach errs on the side of cache misses and only returns data from the cache if there's a 100% certainty that this exact query was sent to the database and that its result was cached before. You can see the statistics of your caching behavior in the Prisma Postgres dashboard: Let's now assume our query from before continues to travel down the Prisma Postgres stack and is not served by the cache. What happens next? ### Stage 4: Hitting the connection pool If the query result has not been cached, the HTTP request from before will be forwarded to the next stop: Prisma Postgres' connection pool (which is deployed on VMs running in close physical proximity to the database instances). > Learn more about why connection pooling is important in our recent article: [Saving Black Friday With Connection Pooling](https://www.prisma.io/blog/saving-black-friday-with-connection-pooling) Note that this is actually the first (and only) time the request may travel a longer distance because it now leaves the regional bounds of a [Cloudflare region](https://www.cloudflare.com/en-gb/network/). These VMs host the Query Engine that was moved out of the application server (as explained in stage 1). So, at this stage, Prisma Postgres' connection pool not only finds an idle connection to actually execute the query, it also generates the SQL statement that will be sent to Prisma Postgres. This is now done via a good old TCP connection to the database. ### Stage 5: Entering the unikernel database Prisma Postgres is based on _unikernels_ (think: "hyper-specialized operating systems") running as ultra-lightweight microVMs on our own bare metal servers. > Check out the [Early Access announcement](https://www.prisma.io/blog/announcing-prisma-postgres-early-access#building-a-managed-postgresql-service-on-millisecond-cloud-infrastructure) to learn about the details of that architecture, our collaboration with [Unikraft](https://unikraft.cloud/), and the millisecond cloud stack that enables the performance benefits of Prisma Postgres. Here's an overview of the Unikraft Cloud's [core components](https://unikraft.cloud/how-it-works/) that enables the lightning-fast startup times of Prisma Postgres instances: And this is how these components work together: - **Custom controller and proxy**: A custom platform controller that provides best-in-class, reactive, millisecond semantics and scalability. To make network processing fast, Unikraft Cloud couples this controller with a custom proxy which takes care of load-balancing and is able to very quickly react to incoming requests. This proxy is where Prisma Postgres' TCP connections to the connection pool are being managed. - **Fast Virtual Machine Monitor (VMM) based on [Firecracker](https://firecracker-microvm.github.io/) and unikernels**: Unikraft Cloud's unikernels use lean images containing only Prisma Postgres — nothing more. Paired with a modified version of Firecracker VMM, these Prisma Postgres images start lightning fast. - **Snapshotting**: Unikraft Cloud takes memory snapshots of Prisma Postgres instances before scaling them to zero. When waking them up, they resume from the snapshot, which means that VMs are already "warm" and even include already active TCP connections! Thanks to this highly efficient stack, a database instance incurs costs only when you actually use it. This enables us to provide a generous free tier where you can spin up as many free Prisma Postgres instances as you like (as opposed to other providers where you typically need to pay a fixed, monthly cost if you create more than one database instance). Back to our query: After the initial JSON representation of the query has been transformed into an efficient SQL statement, the query finally reaches the database layer via TCP. The PostgreSQL instances are deployed using Unikraft's millisecond cloud stack on our own bare metal servers in close proximity to the connection pool. The first stop here is the [Unikraft proxy](https://unikraft.cloud/how-it-works/#control-plane) which is responsible for maintaining the TCP connections to the connection pool. The proxy now talks to the Unikraft controller which is responsible for managing the _actual_ Prisma Postgres instances. At this point, there are two possible states: - _either_ the target Prisma Postgres instance is already up-and-running; in this case the proxy will go ahead and continue to forward the query directly to it. - _or_ the Prisma Postgres instance is currently "paused"; in this case the proxy will reach out to the Unikraft controller which is responsible for identifying the target Prisma Postgres instance, "waking it" up and informing the proxy about the current instance status. Don't get confused by the "pause" and "wake up" terminology here. Thanks to the ultra-fast VM snapshotting (which happens _in memory_) and the lightweight of the unikernels, each instance can be woken up again in a matter of single-digit milliseconds (which is the secret to why Prisma Postgres instances don't suffer from cold starts). ## What's next for the Prisma Postgres architecture? While we've seen a lot of excitement about the current technology stack and the benefits it provides to developers already, we are not going to stop here! There are a number of additional optimizations that we see possible in future iterations of Prisma Postgres, most notably: We are going to move the connection pool onto the _same machines_ that are running the Prisma Postgres instances: ![Future architecture diagram of Prisma Postgres](https://cdn.sanity.io/images/p2zxqf70/production/e6d5ed34c551a50fe047743347f2d0165d62f214-714x859.png) The TCP connection is the most expensive part in the entire stack, due to the three-way handshake that needs to be done every time a connection is established. By reducing this TCP connection to a merely local one happening between two processes on the same machine, the latency caused by the physical distance between the connection pool and database instance would become entirely negligible. This is the core advantage of Prisma Postgres compared to other providers that are based on AWS (or another cloud provider's) infrastructure: When using a cloud provider, there's no guarantee that the connection pool and database instance are running on the same host but there's always going to be a network hop. ## Conclusion In this article, we looked under the covers of Prisma Postgres and the next-generation technology stack it's built on. If you are already using Prisma ORM, give Prisma Postgres a try [by importing the data from your existing database](https://www.prisma.io/docs/getting-started/prisma-postgres/import-from-existing-database) in . Otherwise, try out Prisma Postgres from scratch by running this command in your terminal: ``` npx prisma@latest init --db ``` --- ## [The Ultimate Guide to Testing with Prisma: Unit Testing](/blog/testing-series-2-xPhjjmIEsM) **Meta Description:** Learn about what unit testing is and how to approach it in an application using Prisma Client. **Content:** ## Table Of Contents - [Table Of Contents](#table-of-contents) - [Introduction](#introduction) - [What is unit testing?](#what-is-unit-testing) - [What isn't unit testing?](#what-isnt-unit-testing) - [Technologies you will use](#technologies-you-will-use) - [Prerequisites](#prerequisites) - [Assumed knowledge](#assumed-knowledge) - [Development environment](#development-environment) - [Explore the API](#explore-the-api) - [Set up Vitest](#set-up-vitest) - [Files that don't need to be tested](#files-that-dont-need-to-be-tested) - [What you will test](#what-you-will-test) - [Test the tags service](#test-the-tags-service) - [Test the `upsertTags` function](#test-the-upserttags-function) - [Test the `deleteOrphanedTags` function](#test-the-deleteorphanedtags-function) - [Summary & What's next](#summary--whats-next) ## Introduction Unit testing is one of the primary methods of ensuring the individual units of code (e.g. a _function_) in your applications function as you'd expect them to. It can be very difficult for someone new to testing to understand what unit testing is. Not only do they have to understand how their application works, how to write tests, and how to prepare a testing environment, but they also have to understand what they should be testing for! For that reason, developers often take this approach to testing: > **Note**: Shoutout to [@RoxCodes](https://twitter.com/RoxCodes) for his honesty 😉 In this series, you will be working with a fully functional application. The only thing missing in its codebase is a suite of tests to validate it works as intended. Over the course of this series you will consider various areas of the code and walk through what should be tested, why it needs to be tested, and how to write those tests. This will include *unit testing*, *integration testing*, *end-to-end testing*, as well as setting up *Continuous Integration*(CI) and *Continuous Development*(CD) workflows that run those tests. In this article specifically, you will zoom into specific areas of the code and write unit tests against them to ensure the individual building blocks of those areas are working properly. ### What is unit testing? *Unit testing* is a type of testing that involves writing tests against small, isolated pieces of code. Unit tests target small units of code to ensure they work as expected in various situations. Typically, a unit test will target an individual `function` as functions are usually the smallest singular units of code in a JavaScript application. Take the function below as an example: ```ts function reverseString(str) { return str.split('').reverse().join('') } ``` This function, while simple, is a good candidate for a unit test. It contains a singular set of functionality wrapped into one function. To ensure this function works properly, you might provide it the string `'abcde'` and make sure the string `'edcba'` is returned. The associated _suite_ of tests, or set of tests, could look like the following: ```ts import { it } from 'vitest' import { reverseString } from './utils' it('reverses a string', () => { const string = reverseString('abcde') expect(string).toBe('edcba') }) ``` ```ts import { it } from 'vitest' import { reverseString } from './utils' it('throws an error if given an invalid input', () => { expect(() => reverseString(1)).toThrow() }) ``` As you may have noticed above, the goal of a unit test is simply to ensure the smallest _building blocks_ of your application work properly. In doing this, you build the confidence that as you begin to combine those building blocks the resulting behavior is predictable. Test graphic The reason this is so important is illustrated above. When running your unit tests, if all tests pass you can be sure every building block works and, as a result, your application works as intended. If even one test fails, however, you can assume your application is not working as intended and you will know based on the failed test(s) exactly what is wrong. ### What isn't unit testing? In a unit test, the goal is to make sure your custom code works as intended. The important thing to note from the previous sentence is the phrase _"custom code"_. As a JavaScript developer, you have access to a rich ecosystem of community-built modules and packages via [npm](https://www.npmjs.com/). Using external libraries allows you to save a lot of time where you might otherwise re-invent the wheel. While there is nothing wrong with using an external module, there are some considerations to make when thinking about testing functions that use those modules. Most importantly, it is important to keep this in mind: > If you don't trust an external package and feel you should write tests against it, you probably should not be using that particular package. Take the following function as an example: ```ts import randomColor from 'randomColor' function getSquare(side: number) { if (side <= 0) return null return { height: side, width: side, area: side * side, color: randomColor() } } ``` This function takes in the length of one side of a square and returns an object containing a more defined square, including a unique color for the square. You may want to verify the following when writing unit tests for the function above: - The function returns `null` when a number smaller than one is provided - The function calculates the area properly - The function returns an object of the correct shape with the correct values - The `randomColor` function was invoked once Notice there is no mention of a test to make sure each square actually gets a unique color. This is because `randomColor` is assumed to work properly as it is an external module. >**Note**: Whether `randomColor` was provided via an npm package or even a custom-built function in another file, it should be assumed to work correctly in this context. If `randomColor` was a function you wrote in another file, it should be tested in its own isolated context. Think 'building blocks'! This concept is important because it also applies to Prisma Client. When using Prisma in your application, Prisma Client is an _external module_. Because of this, any tests should assume the functions provided by your client work as expected. ### Technologies you will use - [Vitest](https://vitest.dev/) - [Prisma](https://www.prisma.io/) - [Node.js](https://nodejs.org/en/) - [Express](https://expressjs.com/) ## Prerequisites ### Assumed knowledge The following would be helpful to have coming in to this series: - Basic knowledge of JavaScript or TypeScript - Basic knowledge of Prisma Client and its functionalities - Some experience with Express would be nice ### Development environment To follow along with the examples provided, you will be expected to have: - [Node.js](https://nodejs.org) installed - A code editor of your choice _(we recommend [VSCode](https://code.visualstudio.com/))_ - [Git](https://github.com/git-guides/install-git) installed This series will make heavy use of this [GitHub repository](https://github.com/sabinadams/express_sample_app). Make sure to clone the repository and check out the `main` branch. ### Clone the repository In your terminal head over to a directory where you store your projects. In that directory run the following command: ```sh copy git clone git@github.com:sabinadams/express_sample_app.git ``` The command above will clone the project into a folder named `express_sample_app`. The default branch for that repository is `main`, so at this point you should be ready to go! Once you have cloned the repository, there are a few steps to take to set the project up. First, navigate into the project and install the `node_modules`: ```sh copy cd express_sample_app npm i ``` Next, create a `.env` file at the root of the project: ```sh copy touch .env ``` This file should contain a variable named `API_SECRET` whose value you can set to any `string` you want as well as one named `DATABASE_URL` which can be left empty for now: ```bash copy # .env API_SECRET="supersecretstring" DATABASE_URL="" ``` In `.env` the `API_SECRET` variable provides a _secret key_ used by the authentication services to encrypt your passwords. In a real-world application this value should be replaced with a long random string with numeric and alphabetic characters. The `DATABASE_URL`, as the name suggests, contains the URL to your database. You currently do not have or need a real database. Last, you will need to generate Prisma Client based on your Prisma schema: ```sh copy npx prisma generate ``` ## Explore the API Now that you have a general idea of what unit testing is and isn't, take a look at the application you will be testing in this series. The project you cloned from Github contains a fully functional Express API. This API allows a user to log in, store and organize their favorite quotes. The application's files are organized by feature into folders within the `src` directory. Within `src` there are three main folders: - `/auth`: Contains all files directly related to the authentication of the API - `/quotes`: Contains all files directly related to the quotes feature of the API - `/lib`: Contains any general helper files The API itself offers the following endpoints: | endpoint | description | | -------- | ----------- | | `POST /auth/signup`| Creates a new user with a username and password. | | `POST /auth/signin`| Logs a user in with a username and a password. | | `GET /quotes`| Returns all quotes related to the logged in user. | | `POST /quotes`| Stores a new quote related to the logged in user. | | `DELETE /quotes/:id`| Deletes a quote belonging to the logged in user by id. | Feel free to take some time to explore the files in this project and get a feel for how the API works. With a general understanding of what unit testing is and how the application works, you are now ready to start the process of writing tests to verify the application does what is intended. > **Note**: In a real-world setting, these tests would help ensure that as the application evolves and changes, existing functionality remains intact. Tests would likely be written as you develop the application rather than after the application is complete. ## Set up Vitest In order to begin testing, you will need to have a testing framework set up. In this series you are using [Vitest](https://vitest.dev/). Begin by installing [`vitest`](https://github.com/vitest-dev/vitest) and [`vitest-mock-extended`](https://github.com/eratio08/vitest-mock-extended) with the following command: ```sh copy npm i -D vitest vitest-mock-extended ``` > **Note**: For information regarding the two packages installed above, be sure to read the [first article](/testing-series-1-8eRB5p0Y8o#mock-prisma-client) in this series. Next, you will need to configure Vitest so it knows where your unit tests are and how to resolve any modules you may need to import into those tests. Create a new file at the root of your project named `vitest.config.unit.ts`: ```sh copy touch vitest.config.unit.ts ``` This file will define and export the configuration for your unit tests using the [`defineConfig`](https://vitest.dev/config/#configuration) function provided by Vitest: ```ts copy // vitest.config.unit.ts import { defineConfig } from 'vitest/config' export default defineConfig({ test: { include: ['src/**/*.test.ts'] }, resolve: { alias: { auth: '/src/auth', quotes: '/src/quotes', lib: '/src/lib' } } }) ``` Above you configured two options for Vitest: - The `test.include` option tells Vitest to look for tests within any files in the `src` directory that match the naming convention `*.test.ts`. - The `resolve.alias` configuration sets up file path aliases. This allows you to shorten file import paths, e.g.: `src/auth/auth.service` becomes `auth/auth.service`. Lastly, in order to more easily run your tests you will configure scripts in `package.json` to run the Vitest CLI commands. Add the following to the `scripts` section of `package.json`: ```json copy { // ... "scripts": { "dev": "ts-node src/index.ts", "lint": "eslint . --ext .ts,.tsx --fix", "lint:check": "eslint . --ext .ts,.tsx --max-warnings 0", "format": "prettier --write .", "format:check": "prettier --check .", "checks": "npm run format:check && npm run lint:check", "checks:fix": "npm run format && npm run lint", "prepare": "husky install", + "test:unit": "vitest -c ./vitest.config.unit.ts", + "test:unit:ui": "vitest -c ./vitest.config.unit.ts --ui" }, // ... } ``` Above two new scripts were added: - `test:unit`: This runs the `vitest` CLI command using the configuration file you created above. - `test:unit:ui`: This runs the `vitest` CLI command using the configuration file you created above in _ui mode_. This opens up a GUI in your browser with tools to search, filter, and view the results of your tests. To run these commands, you can execute the following in your terminal at the root of your project: ```sh copy npm run test:unit npm run test:unit:ui ``` > **Note**: If you run either of these commands right now, you will find the command fails. That is because there are no tests to run! At this point, Vitest is configured and you are ready to begin thinking about writing your unit tests. ## Files that don't need to be tested Before jumping right in to writing tests, you will first take a look at the files that _don't_ need to be tested and think about why. Below is a list of files that do not need to be tested: - `src/index.ts` - `src/auth/auth.router.ts` - `src/auth/auth.schemas.ts` - `src/quotes/quotes.router.ts` - `src/quotes/quotes.schemas.ts` - `src/quotes/quotes.service.ts` - `src/lib/prisma.ts` - `src/lib/createServer.ts` These files do not have any custom behaviors that require a unit test. In the next two sections you will take a look at the two primary scenarios in these files that cause them to not require tests. ### The file doesn't have custom behavior Look at the following examples from the application: ```ts // src/quotes/quotes.router.ts import * as QuoteController from './quotes.controller' import { CreateQuoteSchema, DeleteQuoteSchema } from './quotes.schemas' import { Router } from 'express' import { validate } from 'lib/middlewares' const router = Router() router.get('/', QuoteController.getAllQuotes) router.post('/', validate(CreateQuoteSchema), QuoteController.createQuote) router.delete('/:id', validate(DeleteQuoteSchema), QuoteController.deleteQuote) export default router ``` ```ts // src/auth/auth.schemas.ts import { z } from 'zod' export const SignupSchema = z.object({ body: z.object({ username: z.string(), password: z.string() }) }) export type SignupSchema = z.infer['body'] export const SigninSchema = SignupSchema export type SigninSchema = SignupSchema ``` In `src/quotes/quotes.router.ts`, the only things actually happening are invocations of functions provided by the Express framework. There are a few custom functions (`validate` and `QuoteController.*`) in play, however those are defined in separate files and will be tested in their own context. The second file, `src/auth/auth.schemas.ts`, is very similar. While this file is important to the application, there really isn't anything here to test. The code simply exports schemas defined using the external module [`zod`](https://github.com/colinhacks/zod). ### The functions only invokes an external module Another scenario that is important to point out is the one in `src/quotes/quotes.service.ts`: ```ts // src/quotes/quotes.service.ts import prisma from 'lib/prisma' // ... export const deleteQuote = async (id: number) => { return await prisma.quote.delete({ where: { id } }) } ``` This service exports two functions. Both functions wrap a Prisma Client function invocation and return the results. As was mentioned previously in this article, there is no need to test external code. For that reason this file can be skipped. If you take a look at the remaining files from the list above that do not need tests, you will find each one does not need tests for one of the reasons outlined here. ## What you will test The remaining `.ts` files in the project all contain functionality that should be unit tested. The complete list of files that require tests is as follows: - `src/auth/auth.controller.ts` - `src/auth/auth.service.ts` - `src/lib/middlewares.ts` - `src/lib/utility-classes.ts` - `src/quotes/quotes.controller.ts` - `src/quotes/tags.service.ts` Each function in each of these files should be given its own suite of tests that verify it behave correctly. As you might imagine, this can result in a lot of tests! To put this into numbers, the Express API contains thirteen different functions that need to be tested and each will likely have a suite of more than two tests. This means at the very least there will be twenty-six tests to write! In order to keep this article to a manageable length, you will write the tests for a single file, `src/quotes/tags.service.ts` as this file's tests cover all of the important unit-testing concepts this article hopes to cover. > **Note**: If you are curious about what the entire set of tests would look like for this API, the [`unit-tests`](https://github.com/sabinadams/express_sample_app/tree/unit-tests) branch of the Github repository has a complete set of tests for every function. ## Test the tags service The tags service exports two functions, `upsertTags` and `deleteOrphanedTags`. ```ts import prisma from 'lib/prisma' import randomColor from 'randomcolor' export const upsertTags = async (tags: string[]) => { return await prisma.$transaction(async tx => { const existingTags = await tx.tag.findMany({ select: { id: true, name: true }, where: { name: { in: tags } } }) const existingNames = existingTags.map(tag => tag.name) const existingIDs = existingTags.map(tag => tag.id) const createdCount = await tx.tag.createMany({ data: tags .filter(tag => !existingNames.includes(tag)) .map(tag => ({ name: tag, color: randomColor({ luminosity: 'light' }) })) }) const tagIds = existingTags.map(tag => tag.id) if (createdCount.count) { const createdTags = await tx.tag.findMany({ select: { id: true }, where: { name: { in: tags }, id: { notIn: existingIDs } } }) const createdIds = createdTags.map(tag => tag.id) tagIds.push(...createdIds) } return tagIds }) } export const deleteOrphanedTags = async (ids: number[]) => { return await prisma.tag.deleteMany({ where: { quotes: { none: {} }, id: { in: ids } } }) } ``` To start, create a new file in the same directory as `tags.service.ts` named `tags.service.test.ts`: ```sh copy mkdir src/quotes/tests touch src/quotes/tests/tags.service.test.ts ``` > **Note**: There are many ways to organize your tests. In this series, the tests will be written in a file right next to the target of the test, also known as colocating your tests. If you are using [VSCode](https://code.visualstudio.com/) and have v1.64 or later you have access to a cool feature that cleans up your project's file tree when colocating tests and their targets. Within VSCode, head to **Code > Preferences > Settings** in the option bar at the top of the screen. Within the settings page, search for the file nesting setting by typing in `file nesting`. Enable the setting below: File nesting option in VSCode Next, scrolling a bit further down in those settings you will see a **Explorer > File Nesting: Patterns** section. If an item named **\*.ts** does not exist, create one. Then update the **\*.ts** item's value to `${capture}.*.ts`: File nesting setting in VSCode This lets VSCode to nest any files under the main file named `${capture}.ts`. To better illustrate, see the following example: Nested files Above you can see a file named `quotes.controller.ts`. Nested under that file is `quotes.controller.test.ts`. While not strictly necessary, this setting may help clean up your file tree a bit when colocating your unit tests. ### Import required modules At the top of the new `tags.service.test.ts` file you will need to import a few things that will allow you to write your tests: ```ts copy // src/quotes/tags.service.test.ts import * as TagService from '../tags.service' import prismaMock from 'lib/__mocks__/prisma' import randomColor from 'randomcolor' import { describe } from 'vitest' ``` Below is what each of these imports will be used for: - `TagsService`: This is the service you are writing tests against. You need to import it so you can invoke its functions. - `prismaMock`: This is the mocked version of Prisma Client provided at `lib/__mocks__/prisma`. - `randomColor`: The library used within the `upsertTags` function to generate random colors. - `describe`: A function provided by `vitest` that allows you to describe a suite of tests. Important to note is the `prismaMock` import. This is the mocked Prisma Client instance which allows you to perform prisma queries without actually hitting a database. Because it is mocked, you can also manipulate the query responses and spy on its methods. >**Note**: If you are unsure about what the `prismaMock` import is and how it works, be sure to read the [previous article](/testing-series-1-8eRB5p0Y8o) in this series where this module's role is explained. ### Describe the test suite You can now _describe_ this particular set of tests using the [`describe`](https://vitest.dev/api/#describe) function provided by Vitest: ```ts copy // src/quotes/tags.service.test.ts // ... describe('tags.service', () => {}) ``` This will group the tests within this file into one section when outputting the test results making it easier to see which suites passed and failed. ### Mock any modules used by the target file The last thing to do before writing the actual test suite is mock the external modules used within the `tags.service.ts` file. This will give you the ability to control the output of those modules as well as ensure your tests are not polluted by external code. Within this service there are two modules to mock: `PrismaClient` and `randomColor`. Mock those modules by adding the following: ```ts copy // src/quotes/tags.service.test.ts // ... // Added `beforeEach` and `vi` 👇🏻 import { describe, beforeEach, vi } from 'vitest' vi.mock('lib/prisma') vi.mock('randomcolor', () => ({ default: vi.fn(() => '#ffffff') })) describe('tags.service', () => { beforeEach(() => { vi.restoreAllMocks() }) }) ``` Above, the `lib/prisma` module was mocked using Vitest's automatic mock detection algorithm which looks in the same directory as the "real" Prisma module for a folder named `__mocks__` and a `__mocks__/prisma.ts` file. This file's exports are used as the mocked module in place of the real module's exports. The `randomColor` mock is a bit different as the module exports only a default value, which is a function. The second parameter of `vi.mock` is a function that returns the object the module should return when imported. The snippet above adds a `default` key to this object and sets its value to a spyable function with a static return value of `'#ffffff'`. Within the test suite's context, [`beforeEach`](https://vitest.dev/api/#beforeeach) and [`vi.restoreAllMocks`](https://jestjs.io/docs/jest-object#jestrestoreallmocks) are used to ensure that between every individual test the mocks are restored to their original state. This is important as in some tests you will modify the behavior of a mock for that specific test. > **Note**: If you are unsure about how these mocks work, be sure to refer to the [previous article](/testing-series-1-8eRB5p0Y8o) in this series where mocking was covered. Whenever these modules are imported within `TagsService`, the mocked versions will now be imported instead. ### Test the `upsertTags` function The `upsertTags` function takes in an array of tag names and creates a new tag for each name. It will not create a tag, however, if an existing tag in the database has the same name. The returned value of the function is the array of tag IDs associated with all of the tag names provided to the functions, both new and existing. Right below the `beforeEach` invocation within the test suite, add another `describe` to describe the suite of tests relating to the `upsertTags` function. Again, this is done to group the output of the tests making it easy to see which tests related to this specific function passed. ```ts copy // src/quotes/tags.service.test.ts //... describe('tags.service', () => { beforeEach(() => { vi.restoreAllMocks() }) + describe('upsertTags', () => {}) }) ``` Now it is time to decide what the tests you write should cover. Taking a look at the `upsertTags` function, consider what specific behaviors it has. Each desired behavior should be tested. Below, comments have been added showing each behavior that should be tested in this function. The comments are numbered, indicating which order the tests will be written in: ```ts // src/quotes/tags.service.ts // ... export const upsertTags = async (tags: string[]) => { return await prisma.$transaction(async tx => { const existingTags = await tx.tag.findMany({ select: { id: true, name: true }, where: { name: { in: tags } } }) const existingNames = existingTags.map(tag => tag.name) const existingIDs = existingTags.map(tag => tag.id) // 2. should only create tags that do not already exist const createdCount = await tx.tag.createMany({ data: tags .filter(tag => !existingNames.includes(tag)) .map(tag => ({ name: tag, // 3. should give new tags random colors color: randomColor({ luminosity: 'light' }) })) }) const tagIds = existingTags.map(tag => tag.id) // 4. should find and return new tag IDs if (createdCount.count) { const createdTags = await tx.tag.findMany({ select: { id: true }, where: { name: { in: tags }, id: { notIn: existingIDs } } }) const createdIds = createdTags.map(tag => tag.id) tagIds.push(...createdIds) } // 1. should return a list of tag IDs // 5. should return an empty array if no tags are passed return tagIds }) } ``` With a list of scenarios to test ready, you can now begin to write tests for each of them. #### Validate the function returns a list of tag IDs The first test will ensure that the returned value of the function is an array of tag IDs. Within the `describe` block for this function, add the new test: ```ts copy // src/quotes/tags.service.test.ts // ... // Added `it` 👇🏻 import { beforeEach, describe, expect, it, vi } from 'vitest' // ... describe('tags.service', () => { beforeEach(() => { vi.restoreAllMocks() }) describe('upsertTags', () => { it('should return a list of tagIds', async () => { // 1 prismaMock.$transaction.mockResolvedValueOnce([1, 2, 3]) // 2 const tagIds = await TagService.upsertTags(['tag1', 'tag2', 'tag3']) // 3 expect(tagIds).toStrictEqual([1, 2, 3]) }) }) }) ``` The test above does the following: 1. Mocks the response of Prisma Client's `$transaction` function 2. Invokes the `upsertTags` function 3. Ensures the response of the function is equal to the expected mocked response of `$transaction` This test is important as it specifically tests for the desired outcome of the function. If this function were to change in the future, this test ensures that the results of the function remain what is expected. > **Note**: If you are unsure what a specific method provided by Vitest does, please refer to Vitest's [documentation](https://vitest.dev/api/expect.html). If you now run `npm run test:unit` you should see your test pass successfully. #### Validate the function only creates tags that do not already exist The next test planned above will verify that the function does not create duplicate tags in the database. The function is provided a list of strings that represent tag names. The function first checks for existing tags with those names and based on the results filters creates only new tags. The test should: - Mock the first invocation of `prisma.tag.findMany` to return a single tag. This signifies that one existing tag was found based on the names provided to the function. - Invoke `upsertTags` with three tag names. One name should be `tag1`, the name of the mocked existing tag. - Ensure `prisma.tag.createMany` was provided only the two tags that did not match `tag1`. Add the following test below the previous test within the `describe` block for the `upsertTags` function: ```ts copy // src/quotes/tags.service.test.ts // ... describe('tags.service', () => { beforeEach(() => { vi.restoreAllMocks() }) describe('upsertTags', () => { // ... it('should only create tags that do not already exist', async () => { // Mock the `$transaction` function and configure it to use the mocked Prisma Client prismaMock.$transaction.mockImplementationOnce( callback => callback(prismaMock) ) // Mock the first invocation of `findMany` prismaMock.tag.findMany.mockResolvedValueOnce([ { id: 1, name: 'tag1', color: '#ffffff' } ]) // Mock the resolved value of `createMany` to avoid invoking the real function prismaMock.tag.createMany.mockResolvedValueOnce({ count: 0 }) // Invoke `upsertTags` with three tags, including `'tag1'` await TagService.upsertTags(['tag1', 'tag2', 'tag3']) // Ensure that only `'tag2'` and `'tag3'` are provided to `createMany` expect(prismaMock.tag.createMany).toHaveBeenCalledWith({ data: [ { name: 'tag2', color: '#ffffff' }, { name: 'tag3', color: '#ffffff' } ] }) }) }) }) ``` Running `npm run test:unit` again should now show both of your passing tests. #### Validate the function gives new tags a random color In this next test you will need to verify that whenever a new tag is created, it is provided a new random color. In order to do this, write a basic test that inserts three new tags. After the `upsertTags` function is invoked, you can then ensure that the `randomColor` function was invoked three times. The snippet below shows what this test should look like. Add the new test below the previous test you wrote within the `describe` block for the `upsertTags` function: ```ts copy // src/quotes/tags.service.test.ts // ... describe('tags.service', () => { beforeEach(() => { vi.restoreAllMocks() }) describe('upsertTags', () => { // ... it('should give new tags random colors', async () => { // Again, configuring the `$transaction` function to use the mocked client prismaMock.$transaction.mockImplementationOnce(callback => callback(prismaMock) ) // Ensure there are no existing tags found prismaMock.tag.findMany.mockResolvedValue([]) // Mock the resolved value of `createMany` so the real function isn't invoked prismaMock.tag.createMany.mockResolvedValueOnce({ count: 3 }) // Invoke the function with three new tags await TagService.upsertTags(['tag1', 'tag2', 'tag3']) // Validate the `randomColor` function was called three times expect(randomColor).toHaveBeenCalledTimes(3) }) }) }) ``` The `npm run test:unit` command should result in three successful tests. You may be wondering how the test above was able to check how many times `randomColor` was invoked. Remember, within the context of this file the `randomColor` module was mocked and its default export was configured to be a `vi.fn` that provides a function that returns a static string value. Because `vi.fn` was used, the mocked function is now registered within Vitest as a function you can _spy_ on. As as result, you have access to special properties such as a count of how many times the function was invoked during the current test. #### Validate the function includes the newly created tag IDs in its returned array In this test, you will need to verify that the function returns the tag IDs associated with every tag name provided to the function. This means it should return existing tag IDs and the IDs of any newly created tags. This test should: 1. Cause the first invocation of `tag.findMany` to return a tag to simulate finding an existing tag 2. Mock the response of `tag.createMany` 3. Cause the second invocation of `tag.findMany` to return two tags, signifying it found the two newly created tags 4. Invoke the `upsertTags` function with three tags 5. Ensure all three IDs are returned Add the following test to accomplish this: ```ts copy // src/quotes/tags.service.test.ts // ... it('should find and return new tagIds when creating tags', async () => { prismaMock.$transaction.mockImplementationOnce(callback => callback(prismaMock) ) // Simulate finding an existing tag prismaMock.tag.findMany.mockResolvedValueOnce([ { id: 1, name: 'tag1', color: '#ffffff' } ]) prismaMock.tag.createMany.mockResolvedValueOnce({ count: 3 }) // Simulate finding two newly created tags prismaMock.tag.findMany.mockResolvedValueOnce([ { id: 2, name: 'tag2', color: '#ffffff' }, { id: 3, name: 'tag3', color: '#ffffff' } ]) // Invoke the function with three tags await TagService.upsertTags(['tag1', 'tag2', 'tag3']) // Expect the transaction to have returned with all of the ids expect(prismaMock.$transaction).toHaveReturnedWith([1, 2, 3]) }) ``` Verify the test above works by running `npm run test:unit`. #### Validate the function returns an empty array when not provided any tag names As you might expect, if no tag names are provided to this function it should not be able to return any tag IDs. In this test, verify that this behavior is working by adding the following: ```ts copy // src/quotes/tags.service.test.ts // ... it('should return an empty array if no tags passed', async () => { prismaMock.$transaction.mockImplementationOnce(callback => callback(prismaMock) ) // Ensure that all `findMany` and `createMany` invocations return empty results prismaMock.tag.findMany.mockResolvedValueOnce([]) prismaMock.tag.createMany.mockResolvedValueOnce({ count: 0 }) prismaMock.tag.findMany.mockResolvedValueOnce([]) // Invoke `upsertTags` with no tag names await TagService.upsertTags([]) // Ensure an empty array is returned expect(prismaMock.$transaction).toHaveReturnedWith([]) }) ``` With that, all of the scenarios that were determined for this function have been tested! If you run your tests using either of the scripts you added to `package.json` you should see that all of the tests run and pass successfully! ```sh copy npm run test:unit:ui ``` > **Note**: If you had not yet run this command you may be prompted to install the `@vitest/ui` package and re-run the command. Successful suite of tests ### Test the `deleteOrphanedTags` function This function is a very different scenario than the previous function. ```ts // src/quotes/tags.service.ts export const deleteOrphanedTags = async (ids: number[]) => { return await prisma.tag.deleteMany({ where: { quotes: { none: {} }, id: { in: ids } } }) } ``` As you may have already determined, this function simply wraps an invocation of a Prisma Client function. Because of that... you guessed it! This function does not actually require a test! ## Summary & What's next During the course of this article you: - Learned what unit testing is and why it is important to your applications - Saw a few examples of situations where unit testing is not strictly necessary - Set up Vitest - Learned a few tricks to make life easier when writing tests - Tried your hand at writing unit tests for a service in the API While only one file from the quotes API was covered in this article, the concepts and methods used to test the tags service also apply to the rest of the application. I would encourage you to write tests for the remainder of the API to practice! In the next part of this series, you will dive into _integration testing_ and write integration tests for this same application. --- ## [Using GraphQL Nexus with a Database](/blog/using-graphql-nexus-with-a-database-pmyl3660ncst) **Meta Description:** No description available. **Content:** > ⚠️ **This article is outdated** as it relates to [Prisma 1](https://github.com/prisma/prisma1) which is now [deprecated](https://github.com/prisma/prisma1/issues/5208). To learn more about the most recent version of Prisma, read the [documentation](https://www.prisma.io/docs). ⚠️ ## Recap: Code-first development with GraphQL Nexus In the last article, we introduced [GraphQL Nexus](https://nexus.js.org/docs/getting-started), a GraphQL library that enables code-first development for TypeScript and JavaScript. With Nexus, the GraphQL schema is defined and implemented _programmatically_. It therefore follows proven approaches of GraphQL servers in other languages, such as [`sangria-graphql`](https://github.com/sangria-graphql/sangria) (Scala), [`graphlq-ruby`](https://github.com/rmosolgo/graphql-ruby) or [`graphene`](https://graphene-python.org/) (Python). Today's article is about connecting your Nexus-based GraphQL server to a database, using the Prisma client as well as the new [`nexus-prisma`](https://github.com/prisma/nexus-prisma) plugin. We'll later walk you through a practical example of building a GraphQL API for a blogging app from scratch. > `nexus-prisma` works with PostgreSQL, MySQL and MongoDB. **Find the docs for it [here](https://nexus.js.org/docs/nexus-prisma)**. --- ## TLDR: Benefits of the `nexus-prisma` plugin - CRUD operations for your Prisma models in GraphQL - Customize your Prisma models, e.g. _hide certain fields_ or _add computed fields_ - Full type-safety: Coherent set of types for GraphQL schema and database - Compatible with the GraphQL ecosystem (e.g. `apollo-server`, `graphql-yoga`, ...) ## Understanding the `nexus-prisma` workflow ### The Prisma client as an ORM replacement If you haven't worked with Prisma before, here's a quick rundown of how it works: 1. Define your datamodel or let Prisma introspect your existing database 1. Generate your Prisma client, i.e. a type-safe database client 1. Use the Prisma client to access your database in an application (e.g. a GraphQL API) ### The `nexus-prisma` plugin under the hood When adding `nexus-prisma` to the mix, there's another step: invoking the `nexus-prisma-generate` codegen CLI. It generates the building blocks of a full-blown GraphQL CRUD API for your Prisma models, e.g. for a **`User`** model it includes: - **Queries** - **`user(...): User!`**: Fetches a single record - **`users(...): [User!]!`**: Fetches a list of records - **`usersConnection(...): UserConnection!`**: [Relay connections](https://graphql.org/learn/pagination/#complete-connection-model) & aggregations - **Mutations** - **`createUser(...): User!`**: Creates a new record - **`updateUser(...): User`**: Updates a record - **`deleteUser(...): User`**: Deletes a record - **`updatesManyUsers(...): BatchPayload!`**: Updates many records in bulk - **`deleteManyUsers(...): BatchPayload!`**: Deletes many records in bulk - [**GraphQL input types**](https://graphql.org/graphql-js/mutations-and-input-types/) - **`UserCreateInput`**: Wraps all fields of the record - **`UserUpdateInput`**: Wraps all fields of the record - **`UserWhereInput`**: Provides filters for all fields of the record - **`UserWhereUniqueInput`**: Provides filters for unique fields of the record - **`UserUpdateManyMutationInput`**: Wraps fields that can be updated in bulk - **`UserOrderByInput`**: Specifies ascending or descending orders by field > `UserCreateInput` and `UserUpdateInput` differ in the way relation fields are treated. When writing your GraphQL server code with `nexus` and `nexus-prisma`, you build upon these operations by exposing and customizing them to your own API needs: After having generated the CRUD building blocks, you can use `prismaObjectType` from `nexus-prisma` to start exposing (and customizing) them. The following code snippets depict an implementation that provides a GraphQL API for a TODO-list app based on Prisma and `nexus-prisma`: ```graphql type Todo { id: ID! @unique title: String! done: Boolean! @default(value: "false") } ``` ```ts import { prismaObjectType } from 'nexus-prisma' import { idArg } from 'nexus-prisma' // Expose the full "Query" building block const Query = prismaObjectType({ name: 'Query', definition: t => t.prismaFields(['*']) }) // Customize the "Mutation" building block const Mutation = prismaObjectType({ name: 'Mutation', definition(t) { // Keep only the `createTodo` mutation t.prismaFields(['createTodo']) // Add a custom `markAsDone` mutation t.field('markAsDone', { args: { id: idArg() }, nullable: true, resolve: (_, { id }, ctx) { return ctx.prisma.updateTodo({ where: { id }, data: { done: true } }) } }) } }) const schema = makePrismaSchema({ types: [Query, Mutation], // More config stuff, e.g. where to put the generated SDL }) // Feed the `schema` into your GraphQL server, e.g. `apollo-server, `graphql-yoga` ``` ```graphql # The fully exposed "Query" building block type Query { todo(where: TodoWhereUniqueInput!): Todo todoes( after: String before: String first: Int last: Int orderBy: TodoOrderByInput skip: Int where: TodoWhereInput ): [Todo!]! todoesConnection( after: String before: String first: Int last: Int orderBy: TodoOrderByInput skip: Int where: TodoWhereInput ): TodoConnection! } # The customized "Mutation" building block type Mutation { createTodo(data: TodoCreateInput!): Todo! markAsDone(id: ID): Todo } # The Prisma model type Todo { done: Boolean! id: ID! title: String! } # More of the generated building blocks: # e.g. `TodoWhereUniqueInput`, `TodoCreateInput`, `TodoConnection`, ... ``` We're applying `prismaObjectType` to `Query` and `Mutation`. For `Query`, we're keeping all fields (i.e. `todo`, `todoes` and `todoesConnection`). For `Mutation` we're using `prismaFields` to customize the exposed operations. `prismaFields` lets us select the operations to be exposed. In this case, we only want to keep the operation to _create_ a model (`createTodo`). From the generated CRUD building blocks, we're including neither `updateTodo` nor `deleteTodo` but implement our own `markAsDone(id: ID!)` mutation that checks off a certain `Todo`. --- ## Example: From standard CRUD to a customized GraphQL API Let's now take a quick tour through a standard Prisma use case and see how to quickly build a GraphQL API for a blogging app in a few easy steps. Here's what we'll do: 1. Setup a Prisma project (using a free demo database) with TypeScript 1. Define models, migrate database and generate the Prisma client 1. Expose full CRUD GraphQL API via `nexus-prisma` 1. Customize the GraphQL API via `nexus-prisma` If you want to follow along, you need to have the Prisma CLI installed: ```bash npm install -g prisma ``` ```bash yarn global add prisma ``` ```bash brew tap prisma/prisma brew install prisma ``` ### 1) Setup Prisma project with TypeScript, `nexus` and `nexus-prisma` This section mostly deals with your project setup. Feel free to skip it if you don't want to code along, otherwise expand the section below. Use the Prisma CLI to create a simple Prisma project: ```bash prisma init myblog ``` In the interactive prompt, select the following options: 1. Select **Demo server** (includes a free & hosted demo database in Prisma Cloud) 1. **Authenticate** with Prisma Cloud in your browser (if necessary) 1. Back in your terminal, **confirm all suggested values** > As an alternative to the Demo server, you can also [run Prisma locally using Docker](https://v1.prisma.io/docs/1.34/prisma-server/deployment-environments/docker-rty1/). Next you need to configure your `nexus-prisma` workflow. Add the following dependencies (inside the `myblog` directory): ```bash npm init -y npm install --save nexus graphql nexus-prisma prisma-client-lib graphql-yoga npm install --save-dev typescript ts-node-dev ``` Next, add the following two lines to the end of your `prisma.yml`: ```yml hooks: post-deploy: - prisma generate - npx nexus-prisma-generate --client ./generated/prisma-client --output ./generated/nexus-prisma ``` This ensures that the Prisma client as well as the generated `nexus-prisma` CRUD building blocks are being updated whenever you make changes to your models. Since we're using TypeScript, let's quickly add a `tsconfig.json`: ```json { "compilerOptions": { "sourceMap": true, "outDir": "dist", "strict": true, "lib": ["esnext", "dom"] } } ``` Finally, go ahead and add a `start` script that you'll use for development. It starts a development server that watches your files in the background and updates the generated SDL and Nexus typings as you code. Add this to your `package.json`: ```json "scripts": { "start": "ts-node-dev --no-notify --respawn --transpileOnly ./" }, ``` ### 2) Define models, migrate database & generate the Prisma client The `prisma init` command created a default `User` model in `datamodel.prisma`. As we're building a blogging application, let's adjust the models to our application domain: ```graphql type User { id: ID! @unique email: String! @unique name: String posts: [Post!]! } type Post { id: ID! @unique createdAt: DateTime! updatedAt: DateTime! published: Boolean! @default(value: "false") title: String! content: String author: User! } ``` Next you need to migrate the database by applying the datamodel to it. Using the following command, each model defined in `datamodel.prisma` will be mapped to a table in the underlying database: ```bash prisma deploy ``` Because you configured the `post-deploy` hook in `prisma.yml` earlier, your Prisma client and the CRUD building blocks are automatically updated. ### 3) Expose full CRUD GraphQL API via `nexus-prisma` In the early phase of a project, it's often helpful to have full CRUD capabilities exposed by an API – more constrained API requirements typically emerge over time. `nexus-prisma` perfectly accounts for that by providing a straightforward path to go from full CRUD to customized API operations. Let's start with a GraphQL API that exposes full CRUD for the defined models (note that this includes filters, pagination and sorting). Create a new file called `index.ts` and add the following code to it: ```ts import * as path from 'path' import { GraphQLServer } from 'graphql-yoga' import { makePrismaSchema, prismaObjectType } from 'nexus-prisma' import { prisma } from './generated/prisma-client' import datamodelInfo from './generated/nexus-prisma' const Query = prismaObjectType({ name: 'Query', definition: t => t.prismaFields(['*']), }) const Mutation = prismaObjectType({ name: 'Mutation', definition: t => t.prismaFields(['*']), }) const schema = makePrismaSchema({ types: [Query, Mutation], prisma: { datamodelInfo, client: prisma, }, outputs: { schema: path.join(__dirname, './generated/schema.graphql'), typegen: path.join(__dirname, './generated/nexus.ts'), }, }) const server = new GraphQLServer({ schema, context: { prisma }, }) server.start(() => console.log(`Server is running on http://localhost:4000`)) ``` > We're not paying much attention to file structure in this short tutorial. Check our [`graphql-auth`](https://github.com/prisma/prisma-examples/tree/master/typescript/graphql-auth) example for a proper setup and modularized schema. After running `npm run start`, you can open the GraphQL Playground for your GraphQL server on `http://localhost:4000`. With the little code you wrote above, you already have a full-blown GraphQL CRUD API at your disposal. #### Example queries ```graphql # Fetch all posts with their authors query { posts { id title published author { id name } } } ``` ```graphql # Fetch a certain user by email query { user(where: { email: "alice@prisma.io" }) { id name posts { id title } } } ``` #### Example mutations ```graphql # Create a post and its author mutation { createPost(data: { title: "Hello World", author: { create: { email: "bob@prisma.io" } } }) { id published author { id name } } } ``` ```graphql # Update the name of a user mutation { updateUser(data: { name: "Alice" }, where: { email: "alice@prisma.io " }) { id name } } ``` ```graphql # Delete a user mutation { deleteUser(where: { email: "alice@prisma.io " }) { id name } } ``` How does that work? `nexus-prisma-generate` generated a GraphQL schema that provides a CRUD API for Prisma models (your _CRUD building blocks_). This GraphQL schema follows the [OpenCRUD](https://www.opencrud.org/) specification. Using the `prismaObjectType` function, you can now expose and customize the operations of that schema. `prismaObjectType` and `prismaFields` use a _whitelist_ approach, meaning you need to explicitly list the fields you want to expose. The wildcard operator `*` includes _all_ fields. ### 4) Customize the GraphQL API via `nexus-prisma` In this section, we'll learn how the CRUD GraphQL API from `nexus-prisma` can be customized. Specifically, we are going to: 1. Hide a field from the `User` model 1. Add a computed field to the `Post` model 1. Hide the `createPost` and `updatePost` mutations 1. Add two custom `createDraft` and `publish` mutations #### 4.1) Hide a field from the `User` model In this section, we'll hide the `email` field from the `User` model. To customize a model, we need to apply the `prismaObjectType` function to it and pass the `definition(t)` function as an option: ```ts const User = prismaObjectType({ name: 'User', definition(t) { t.prismaFields(['id', 'name', 'posts']) }, }) ``` By calling `prismaFields` on the model `t`, we can customize the exposed fields (and their arguments). Because `email` is not included in the list, it's removed from our GraphQL API. To apply the changes, you need to explicitily pass `User` to the `types` array inside of `makePrismaSchema`: ```ts const schema = makePrismaSchema({ types: [Query, Mutation, User], // ... } ``` Note that your editor is able to suggest what to pass into `prismaObjectType` and `prismaFields` based on the generated CRUD building blocks. This means when you type `prismaObjectType('')` and hit **ctrl+space**, it suggests the names of all generated CRUD building blocks. When calling `t.prismaFields([''])`, it suggests the fields of `t`: