Blitz.js采用零API方法将Next.js前端连接到后端数据存储。以下是它的工作原理
Blitz.js是一个基于React和Next.js的新兴JavaScript框架。它是一个全栈的、有主见的框架,这意味着它对如何构建JavaScript应用程序做出了某些假设。Blitz最有趣的方面可能是所谓的零API方法,其中框架完成将用户界面连接到后端数据存储的工作。
让我们亲身体验一下JavaScript应用程序开发的这一有趣而独特的观点。
目录
- 设置闪电战演示
- 创建新项目
- Blitz.js中的RPC
- 身份验证
- 结论
设置闪电战演示
首先,使用以下命令将Blitz添加为全局NPM包:NPM iblitz@alpha-g。现在,您可以使用该工具创建一个新项目,方法是键入:blitz new demo app。清单1显示了演示应用程序的设置。
清单1。创建新的Blitz应用程序
$ blitz new demo-app
✔ Pick which language you'd like to use for your new blitz project › Javascript
✔ Pick which template you'd like to use for your new blitz project › full
✔ Install dependencies? … yes
✔ Pick which form you'd like to use for your new blitz project › React Hook Form
Hang tight while we set up your new Blitz app!
Blitz完成所有依赖项的安装后,您可以移动到刚刚创建的新目录cd demo app中,并使用命令Blitz dev启动开发服务器。该服务器现在运行在localhost:3000上,您将看到一个欢迎屏幕,如下图所示:
图1。闪电战欢迎屏幕。
你可能会注意到的第一件事是,与大多数前端框架不同,Blitz的生成器提供了更精细的全栈脚手架;特别是,支持用户创建和登录。如果你使用这些功能,你会发现你可以创建一个用户并让他们登录和注销。
添加模型
现在,让我们按照欢迎页面的建议,通过命令行添加一个模型。转到命令行并点击CTRL-C以停止开发服务器。输入blitz generate all项目名称:string。这个命令告诉Blitz添加一个新的模型对象,称为project,并使用一个名为name的字符串字段。
通过Prisma迁移数据库
出现提示时,确认要运行prisma migrate dev.Blitz已安装并正在使用基于文件的SQLite数据库,该数据库通过对象关系映射(ORM)层prisma进行映射。SQLite和Prisma是数据对象持久化的位置和方式。prisma migrate dev命令通知prisma更新自身以反映dev数据库(用于开发的默认数据库)中的更改。
2024年IT最佳工作场所提名开放
选择您自己的数据库和ORM层
请注意,Blitz中的数据库和ORM层是模块化的,因此如果您愿意,可以更改默认值并使用MongoDB之类的东西。您需要为Blitz的更改提供一个名称,用于跟踪目的。
创建新项目
生成器完成后,使用命令blitz dev再次启动服务器。返回浏览器并访问localhost:3000/projects。您将看到一个新的用户界面,您可以使用它来创建一个新项目。(点击创建项目。)
如果您在尝试创建新项目时未登录,则会收到消息:“错误:您未通过身份验证。”这将确认授权已在工作。
现在以用户身份登录,然后再次尝试“创建项目”选项。这一次,您将看到一个包含单个名称字段的表单。您可以创建一些项目,您会发现Blitz为您搭建了一个合理的RESTful模式。
localhost:3000/projects页面为您提供了一个项目列表,您可以单击该列表在localhost:3000-projects/<ID>上获取项目详细信息。请注意,您还可以编辑和删除:一个完整的CRUD往返体验。
闪电战项目的布局
让我们来看看Blitz中的项目布局。这让我们感觉到闪电战是如何为我们做这么多的。
/project-root
/db
/db.sqlite
: The SQLite engine and schema/schema.prisma
: The Prisma ORM mappings/migrations
: The directory showing the migrations (useful for rollbacks)
/mailers
: Contains stubs for configuring mailers like the Forgot Password mailer/jest.config.js
: The JEST testing framework config/next.config.js
: The Next.js config file/pages
: The React.js and Next.js front-end files/api
: Support for external (non-Blitz) API access/auth
: The log in, log out, and signup pages/projects
: Pages for theproject
entity. Other objects follow the same pattern.
/test
: Test files (JEST)/app
: App infrastructure/blitz-client.js
: The client-side config/blitz-server.js
: The server-side config/core
: The components, hooks, and layouts for the application/projects
: The queries, mutations, and components for theproject
object/auth
and/user
: Auth related queries, mutations, and components
/integrations
: Third-party integrations like Auth0 and Sentry/package.json
: The Node config file including Blitz scripts likedev
/public
: Static files likefavicon
Blitz.js中的RPC
Blitz最不寻常的地方是它使用了远程过程调用(RPC)。不使用REST或GraphQL API,而是将服务器端代码直接导入客户端JavaScript。Blitz然后将服务器端代码转换为RPC调用。您可以直接从客户端JavaScript访问服务器端代码,Blitz将连接网络交互,使其全部工作。
现在,让我们在blitz-demo/pages/projects/[projectId]/edit.js中打开该文件。请注意,方括号语法是Next.js处理路径阻塞的方式。(projectID变量将暴露给处理请求的页面,在路径中的那个位置保存参数的值。)
清单2包含Blitz演示的主要重要部分。
清单2。项目编辑.js
import { Suspense } from "react";
import Head from "next/head";
import Link from "next/link";
import { useRouter } from "next/router";
import { useQuery, useMutation } from "@blitzjs/rpc";
import { useParam } from "@blitzjs/next";
import Layout from "app/core/layouts/Layout";
import getProject from "app/projects/queries/getProject";
import updateProject from "app/projects/mutations/updateProject";
import { ProjectForm, FORM_ERROR } from "app/projects/components/ProjectForm";
export const EditProject = () => {
const router = useRouter();
const projectId = useParam("projectId", "number");
const [project, { setQueryData }] = useQuery(
getProject,
{ id: projectId },
{ staleTime: Infinity }
);
const [updateProjectMutation] = useMutation(updateProject);
return (
<>
<Head>
<title>Edit Project {project.id}</title>
</Head>
<div>
<h1>Edit Project {project.id}</h1>
<pre>{JSON.stringify(project, null, 2)}</pre>
<ProjectForm
submitText="Update Project" initialValues={project}
onSubmit={async (values) => {
try {
const updated = await updateProjectMutation({
id: project.id,
...values,
});
await setQueryData(updated);
router.push({
pathname: `/projects/[projectId]`,
query: {
projectId: updated.id,
},
});
} catch (error) {
console.error(error);
return {
[FORM_ERROR]: error.toString(),
};
}
}}
/>
</div>
</>
);
};
const EditProjectPage = () => {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<EditProject />
</Suspense>
<p>
<Link
href={{
pathname: "/projects",
}}
>
<a>Projects</a>
</Link>
</p>
</div>
);
};
EditProjectPage.authenticate = true;
EditProjectPage.getLayout = (page) => <Layout>{page}</Layout>;
export default EditProjectPage;
首先,请注意,导入行让我们很好地了解了Blitz的工作原理:该演示导入了React.js、Next.js和Blitz.js库的混合,以及项目特定组件和Blitz生成的RPC。
表单本身是从app/projects/components/ProjectForm.js中提取的,它是从app/core/components/form.js派生而来的。form.js扩展了react钩子表单库,它完成了使表单工作的重任。此外,请注意,表单中预先填充了以下属性:initialValues={project}。页面是如何首先获得项目对象的?
项目对象通过useQuery钩子(来自Blitz)填充,行const[project,{setQueryData}]=useQuery{…}。项目变量设置为最终保存useQuery钩子结果的变量。setQueryData是Blitz中的一个函数,用于更新对象的缓存,使其执行。
有关查询的详细信息
有关useQuery和setQueryData的更多信息,请参阅Blitz文档。
useQuery挂钩依赖于getProject函数,该函数使用路径中的projectId值进行参数化。getProject函数来自app/projects/queries/getProject.js。如果你遵循这个线程,你会发现getProject.js依赖于对db对象的调用,Blitz在/d目录中创建并导出该对象。清单3显示了如何实现getProject调用。
清单3。getProject.js
import db from "db";
//...
const project = await db.project.findFirst({
where: {
id: input.id,
},
})
因此,db对象在项目成员上公开一个查询API。在这里,我们使用它通过标准API找到项目,使用我们传递回的projectId参数。dbneneneba API主要是Prisma库,Blitz用一些助手对其进行了装饰。
对象的突变与对象的创建和查询类似,视图依赖于Blitz基础设施,该基础设施将前端与后端连接起来,而不需要显式的API调用。
身份验证
如果您查看projects/create.js以了解如何在那里处理身份验证,您会注意到导出的页面设置了一个authenticate字段,该字段设置为true,如清单4所示。
清单4。保护页面
NewProjectPage.authenticate = true;
export default NewProjectPage;
Blitz再一次向我们隐藏了很多工作和细节。同样,在主页面/index.js中,当前用户是通过useCurrentUser钩子检索的。在查询和突变的情况下,ctx对象会自动作为参数传入,其中包含会话对象。您可以在稍后的querys/getProject.js文件中看到这一功能,该文件通过检查ctx.session.$isAuthorized()来保护调用。
结论
Blitz是对全栈框架的一种独特而强大的表现。它在幕后做了大量的工作,而没有完全混淆这些底层操作。一旦您了解了Blitz.js及其惯用语,开发就可以沿着许多愉快的道路快速进行,比如围绕基本对象图构建CRUD和执行直接的授权。
- 登录 发表评论