现代网络体系结构无Prisma + Zenstack的后端
#网络开发人员 #database #prisma #fullstack

Web开发的景观在不断变化。我们从提供静态HTML页面的裸金属机开始,到灯堆的上升,然后是平均堆栈,现在是果酱堆栈。

在不同级别的情况下,有两个趋势正在发展:

  • 结构的合并

    开发人员对在应用程序中将许多不同的作品结合在一起感到厌倦。他们已经开始更少的支持:统一的编程语言,单声波,元框架(例如next.js),甚至没有明确编码后端的构建Web应用程序。

  • SQL数据库的复兴

    SQL数据库可能从来没有真正失去NOSQL的任何基础;从时尚的角度来看,使用一段时间就变得不那么酷了。现在,随着越来越多的人意识到,很少有网络应用程序确实是“ Web量表”,而关系数据库仍然是大多数用例的最佳选择,SQL数据库正在卷土重来。

在这篇文章中,我将分享PrismaZenStack的组合与上述两个趋势相对应,以及它们如何帮助您以更少的精力来建立安全的后端。

什么是Prisma

Prisma是JavaScript/Tyspript的ORM工具包。 ORM是一种库,可让您无需编写SQL即可访问数据库。相反,您以与应用程序的其余部分相同的语言编写代码来操纵数据库,ORM库将其转换为SQL查询。

ORM

更具体地说,Prisma是模式优先的ORM,这意味着您首先在模式文件中定义数据模型,然后Prisma为您生成数据库架构和相应的CRUD操作。相反,另一个ORM类别是代码优先:您在编程语言(例如Typescript)中定义数据模型,而ORM则侵入数据库架构。

选择模式优先或代码优先是一个优先问题,尽管模式优先的ORM具有更连贯,简洁且易于阅读的好处。

Schema-first vs code-first

什么是Zenstack

ZenStack是Prisma的扩展,增加了一层安全性。它允许您在架构文件中定义访问控制规则并在运行时注入Prisma查询。

ZModel

此外,它提供了一个恢复的API来访问数据库并为您的前端代码生成客户端库。通过结合访问控制和API生成,Zenstack使得拥有完全安全的CRUD后端而不手动实施。

ZenStack Architecture

他们如何一起工作

Prisma和Zenstack非常适合使用关系数据库建立安全的后端。这是实现它的一般步骤:

1.定义数据模型

使用 zmodel 语言(Prisma架构的超集)来定义您的模型,关系和访问策略。可选,如果您将next.js用作全堆栈框架,请启用React插件来生成数据访问客户端挂钩。

// schema.zmodel

model Post {
  id        String @id @default(cuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  title     String
  published Boolean @default(false)
  author    User @relation(fields: [authorId], references: [id])
  authorId  String

  // author has full access
  @@allow('all', auth() == author)

  // logged-in users can view published posts
  @@allow('read', auth() != null && published)
}

// generate react hooks under ./src/lib/hook
plugin reactHooks {
  provider = '@zenstackhq/react'
  output = "./src/lib/hook
}

2.运行代码生成

使用zenstack cli生成多个代码:

  • 棱镜模式(schema.prism)
  • Prisma客户
  • 在运行时注入Prisma查询的访问策略
  • 数据访问的钩子

CLI Animation

您可以使用生成的schema.prisma迁移数据库的架构和PRISMA客户端,以无需任何访问控制即可访问数据库。您将看到访问策略和反应挂钩接下来的帮助。

3.安装数据访问API

使用特定于框架的软件包安装数据访问API请求处理程序。通常,您通常会使用“增强” Prisma客户端来初始化请求处理程序以保护端点。 “增强”通过加载上一步中生成的访问策略,拦截Prisma客户的操作并注入额外的查询/突变条件来起作用。

这是Next.js:
的示例

// pages/api/model/[...path].ts

// the standard Prisma client
const prisma = new PrismaClient();

// create a Next.js API endpoint handler
export default requestHandler({
    // set up a callback to get a database instance for handling the request
    getPrisma: async (req, res) => {
        // get current user in the session
        const user = await getSessionUser(req, res);

        // return an enhanced Prisma client that enforces access policies
        return withPresets(prisma, { user });
    },
});

4.使用生成的钩子访问数据

使用生成的钩子轻松构建UI零件。挂钩与上一步中安装的数据访问API对话。由于访问策略已经安全了API,因此挂钩将仅返回可读取的实体,并拒绝任何未经授权的突变。

// /src/components/posts.tsx

import { usePost } from '../lib/hooks';

const Posts: FC = () => {
    // "usePost" is a generated hooks method
    const { findMany } = usePost();

    // list unpublished posts together with their author's data,
    // the result "posts" only include entities that are readable
    // to the current user
    const posts = findMany({
        where: { published: false },
        include: { author: true },
        orderBy: { updatedAt: 'desc' },
    });

    // entities are accurately typed based on the query structure
    // posts: Array<Post & { author: user }>
    return (
        <ul>
            {posts.map((post) => (
                <li key={post.id}>
                    {post.title} by {post.author.e}
                </li>
            ))}
        </ul>
    );
};

他们为什么提高您的生产力?

Prisma和Zenstack的组合以几种方式提高了您的发展生产率:

1.您的数据模型的清晰图片

使用DSL来建模您的实体,您始终对应用程序的数据模型进行了明确的描述。

2.靠近数据库的保障

安全性很难部分,因为必须在所有相关的API中始终应用规则。通过声明性地对安全性进行建模,您可以在数据库附近进行保护,并可以避免在添加或更新API时忘记添加必要检查的风险。当需求变化时,调整规则也更容易,因为模式是您的单一真实来源。

3.免费

Prisma客户端(后端)Typescript API提供了出色的类型安全性。感谢Zenstack的客户库一代,您现在可以在前端代码中享受相同的编程体验。

这对我来说是个好选择吗?

Prisma + Zenstack如果适用以下某些情况,可以非常适合您的项目:

  • 您想要一个简单的体系结构,并希望完全使用元框架(例如Next.js或remix.run)构建全堆栈Web应用程序,而无需单独的后端。
  • 您的应用程序具有非平凡的安全要求。
  • 您不是SQL GURU,希望尽可能避免使用复杂的SQL任务。否则,SupabasePostgREST可能是一个更好的选择。
  • 您想避免被锁定在特定的数据库类型或霍斯特中。

包起来

Prisma和Zenstack是通过关系数据库建立安全后端的绝佳组合。希望您发现它对您的下一个项目有用。