📅  最后修改于: 2023-12-03 14:44:18.979000             🧑  作者: Mango
Mirage JS 处理帖子 - Javascript
目录:
Mirage JS 是一个用于模拟前端 Api 数据的库,使开发过程中的调试工作更简单,可以减少开发员与后端服务器的耦合度。它支持构建可靠的测试数据,并具有路由、模型和更多的功能,可以帮助我们更快地开发和测试应用程序的前端部分。
模型是一个与数据库中存储的表结构相关联的概念,它定义了数据的结构和验证行为。在 Mirage JS 中,模型用纯 JavaScript 实现。它可以定义模型字段,模型之间的关系以及他们之间的约束。
我们可以通过 Mirage JS 的 schema.create 方法来定义模型,
import { createServer, Model, Response } from "miragejs";
const server = createServer({
models: {
article: Model,
},
// some other options here
});
在这个例子中,我们定义了一个 article 模型。
你可以通过“属性”来定义一个字段的约束,例如:
const server = createServer({
models: {
article: Model.extend({
title: attr("string"),
}),
},
// some other options here
});
这里,我们定义了一个 article 模型,它具有一个 title 字段,该字段的类型为 “string”。
在 Mirage JS 中,路由定义了一个 API 的实际接口,这是应用程序与后端服务器之间的接口。我们可以通过对路由及其处理程序的设置来模拟服务端的数据返回,这将使我们的应用程序在没有服务器的情况下运行,还可以在开发和测试过程中减少调试和开发时间,使开发过程高效和快速。
const server = createServer({
routes() {
this.get("/api/articles", () => ({
articles: [
{ id: 1, title: "Article 1" },
{ id: 2, title: "Article 2" },
],
}));
},
});
在这段代码中,我们定义了一个路由,这个路由定义了参数,并给这个路由的处理程序返回两篇文章。
const server = createServer({
routes() {
this.get("/api/articles/:id", (schema, request) => {
const id = request.params.id;
const article = schema.articles.find(id);
return { article };
});
},
});
在这个例子中,我们定义了一个带有参数的路由,它接受一个参数 id 作为输入,并返回与该 id 相关联的文章。
Mirage JS 支持通过 schema 定义各种关系,包括一对多、一对一和多对多关系。它还支持一些“后端”功能,例如使用 SQL 进行查询和分页。
const server = createServer({
models: {
user: Model,
article: Model.extend({
author: belongsTo(),
}),
},
routes() {
this.get("/api/users/:id", (schema, request) => {
const userId = request.params.id;
const user = schema.users.find(userId);
const articles = schema.articles.where({ authorId: userId });
return { user, articles };
});
},
});
在这个例子中,我们定义了一个 user 模型和一个 article 模型,article 模型还有一个与 user 模型的 1 对 1 关系,即 author属性,此模型还将我们定义 article 模型的路由处理程序返回文章与作者。
const server = createServer({
models: {
article: Model.extend({
comments: hasMany(),
}),
},
routes() {
this.get("/api/articles", (schema, request) => {
const { page, perPage } = request.queryParams;
const totalCount = schema.articles.all().length;
const articles = schema.articles
.all()
.slice((page - 1) * perPage, page * perPage);
return {
articles,
meta: { page, perPage, totalCount },
};
});
},
});
在这个例子中,我们定义了一个具有“hasMany”关系的文章模型,并定义了一个用于查询和分页的路由。该路由返回一些元数据,例如当前页,每页的文章数以及文章总数。
Mirage JS 还支持通过使用凭证和会话来实现身份验证,以帮助我们实现更安全的应用程序。
const server = createServer({
routes() {
this.post("/api/login", (schema, request) => {
const { email, password } = JSON.parse(request.requestBody);
const user = schema.users.findBy({ email, password });
if (user) {
return { token: "abc123" };
} else {
return new Response(401, {}, { error: "Invalid credentials" });
}
});
this.get("/api/user", (schema, request) => {
const apiKey = request.headers.Authorization.split(" ")[1];
const user = schema.users.findBy({ apiKey });
if (user) {
return user;
} else {
return new Response(401, {}, { error: "Unauthorized" });
}
});
},
});
在这个例子中,我们定义了两个路由,一个是用于模拟用户登录的路由,另一个用于模拟 API 资源中的用户信息。在这个例子中,我们模拟了身份验证、会话和凭证的概念。
要在前端使用 Mirage JS,您需要先将 Mirage JS 导入您的项目。通常,您可以在“测试”或“开发”阶段使用 Mirage JS。
import { createServer } from "miragejs";
createServer({
// your routes and models here
});
再使用了上面的 Mirage JS 的代码后,你可以在 Vue 或 React 的生命周期方法中使用 migratedRoutes 例如。
import { createServer } from "miragejs";
export default {
data() {
return { articles: [] };
},
async created() {
if (process.env.NODE_ENV === "development") {
createServer({
routes() {
this.get("/api/articles", () => ({
articles: [
{ id: 1, title: "Article 1" },
{ id: 2, title: "Article 2" },
],
}));
},
});
}
// Fetch data from /api/articles
const response = await fetch("/api/articles");
const { articles } = await response.json();
this.articles = articles;
},
};
import React, { useState, useEffect } from "react";
import { createServer } from "miragejs";
function ArticleList() {
const [articles, setArticles] = useState([]);
useEffect(() => {
if (process.env.NODE_ENV === "development") {
createServer({
routes() {
this.get("/api/articles", () => ({
articles: [
{ id: 1, title: "Article 1" },
{ id: 2, title: "Article 2" },
],
}));
},
});
}
fetch("/api/articles")
.then((response) => response.json())
.then((data) => setArticles(data.articles));
}, []);
return (
<ul>
{articles.map((article) => (
<li key={article.id}>{article.title}</li>
))}
</ul>
);
}
import { createServer, Model, Response } from "miragejs";
const server = createServer({
models: {
article: Model.extend({
author: belongsTo(),
comments: hasMany(),
}),
user: Model,
comment: Model.extend({
article: belongsTo(),
}),
},
routes() {
this.get("/api/articles", (schema) => schema.articles.all());
this.post("/api/articles", (schema, request) => {
const attrs = JSON.parse(request.requestBody).article;
const author = schema.users.create(attrs.author);
const article = schema.articles.create({ ...attrs, author });
return article;
});
this.get("/api/articles/:id", (schema, request) => {
const id = request.params.id;
const article = schema.articles.find(id);
const comments = server.schema.comments.all().filter((c) => c.articleId === id);
return { id: article.id, ...article.attrs, comments };
});
this.patch("/api/articles/:id", (schema, request) => {
const id = request.params.id;
const attrs = JSON.parse(request.requestBody);
const article = schema.articles.find(id);
return article.update(attrs);
});
this.delete("/api/articles/:id", (schema, request) => {
const id = request.params.id;
const article = schema.articles.find(id);
return article.destroy();
});
this.get("/api/users/:id", (schema, request) => {
const userId = request.params.id;
const user = schema.users.find(userId);
const articles = schema.articles.where({ authorId: userId });
return { user, articles };
});
this.post("/api/login", (schema, request) => {
const { email, password } = JSON.parse(request.requestBody);
const user = schema.users.findBy({ email, password });
if (user) {
return { token: "abc123" };
} else {
return new Response(401, {}, { error: "Invalid credentials" });
}
});
this.get("/api/user", (schema, request) => {
const apiKey = request.headers.Authorization.split(" ")[1];
const user = schema.users.findBy({ apiKey });
if (user) {
return user;
} else {
return new Response(401, {}, { error: "Unauthorized" });
}
});
},
});
// eslint-disable-next-line no-console
console.log(server.db.dump());