MirageJS Part 2 - Main Concepts - Shorthands

API 正变得越发的标准化,因此,Mirage 引入了 路由缩写 shoorthands 的概念来替代许多自定义路由处理器的编写,从而可以更轻松的编写,也极大地简化了路由处理器的定义。

例如,这个非常标准的函数式路由,它将返回一个与路径同名的数据集合:

1
2
3
this.get('/movies', (schema, request) => {
return schema.movies.all()
})

同时,也可以使用路由缩写来完成相同的工作:

1
this.get('/movies')

这是一个完整的路由。它能从路径的最后一部分推断模型名称,并返回同名的数据集合。

如果通过查询 ID 得到单条数据,也是非常简单的:

1
this.get('/movies/:id')

使用路由缩写同样可以完成新建或者编辑数据。这也是一个标准的路由,它使用请求体中的一个属性 movie 来创建一条新的数据:

1
2
3
4
5
this.post('/movies', (schema, request) => {
let attrs = JSON.parse(request.requestBody).movie

return schema.movies.create(attrs)
})

同样的工作也可以使用缩写来完成:

1
this.post('/movies')

路由缩写使用基于 HTTP 动词的默认状态码:

  • GET, PATCH/PUT, DEL 200
  • POST 201

路由缩写:GET 方法(GET Shorthands)

获取集合:

1
2
3
4
5
6
7
8
// Shorthand
this.get("/contacts") // finds type by singularizing url
this.get("/contacts", "users") // optionally specify the collection as second param

// equivalent
this.get("/contacts", (schema) => {
return schema.contacts.all() // users in the second case
})

上面例子中有传入第二参数的用法,我还没试过,不知道是什么情况…

updated: 但是,翻了一下源码,发现第二个参数指的是指定一个用于查询的模型/集合名称。
由于 Mirage 的路由缩写会从请求路径中推断模型/集合名称,当路径中指代的模型/集合名称不是真正的模型/集合时,查询就会出错。

换句话说,你在数据库中定义的模型叫 user ,但是在构建 API 请求路径时使用的是 /contacts ,这必然是查询不到数据的,所以通过第二个参数传入真正的模型/集合名称用于查询。

以上,个人从源码中理解而来,详细例子可以查看路由缩写:resource-方法(Resource-helper)部分。

下面几个路由缩写的例子中,如果不做特别说明,均照此解释。

获取模型:

1
2
3
4
5
6
7
8
9
10
// Shorthand
this.get("/contacts/:id") // finds type by singularizing url
this.get("/contacts/:id", "user") // optionally specify the type as second param

// equivalent
this.get("/contacts/:id", (schema, request) => {
let id = request.params.id

return schema.contacts.find(id) // users in the second case
})

通过多个 ID 获取模型, GET /contacts?ids=1,2,3

1
2
3
4
5
6
7
8
9
10
11
// Shorthand
this.get("/contacts", { coalesce: true })
this.get("/contacts", "users", { coalesce: true })

// equivalent
this.get("/contacts", ({ contacts }, request) => {
let ids = request.queryParams.ids

return contacts.find(ids) // users in the second case
})

路由缩写:POST 方法(POST Shorthands)

创建资源:

1
2
3
4
5
6
7
8
9
10
// Shorthand
this.post("/contacts") // finds type by singularizing url
this.post("/contacts", "user") // optionally specify the type as second param

// equivalent
this.post("/contacts", function (schema, request) {
let attrs = this.normalizedRequestAttrs()

return schema.contacts.create(attrs)
})

注意,要使 POST/PATCH/PUT 缩写生效,Mirage 需要知道应用发送的请求中所使用的 JSON 是哪一种格式,以便 POST 缩写可以用正确的方式将数据插入库中。

更详细的信息请看 serializer部分中 normalize 的内容。

路由缩写:PATCH/PUT 方法(PATCH/PUT Shorthands)

更新资源:

1
2
3
4
5
6
7
8
9
10
11
// Shorthand (these also work with this.put)
this.patch("/contacts/:id") // finds type by singularizing url
this.patch("/contacts/:id", "user") // optionally specify the type as second param

// equivalent
this.patch("/contacts/:id", function (schema, request) {
let id = request.params.id
let attrs = this.normalizedRequestAttrs()

return schema.contacts.find(id).update(attrs)
})

路由缩写:DELETE 方法(DELETE Shorthands)

删除(destroying)资源:

1
2
3
4
5
6
7
8
9
10
// Shorthand
this.del("/contacts/:id") // finds type by singularizing url
this.del("/contacts/:id", "user") // optionally specify the type as second param

// equivalent
this.del("/contacts/:id", (schema, request) => {
let id = request.params.id

schema.contacts.find(id).destroy()
})

删除资源和关系模型中的资源:

1
2
3
4
5
6
7
8
9
10
11
12
// Shorthand
// contact 模型和 addresses 模型是定义好的一对多模型
this.del("/contacts/:id", ["contact", "addresses"])

// equivalent
this.del("/contacts/:id", ({ contacts }, request) => {
let id = request.params.id
let contact = contacts.find(id)

contact.addresses.destroy()
contact.destroy()
})

路由缩写:resource 方法(Resource helper)

需要特别说明一下,this.resource() 的第一参数是集合名称(以模型名称的复数形式表示集合,接触过数据库的应该都知道)。

这个路由缩写可以方便的定义符合 RESTful 规范的资源路由:

1
2
3
4
5
6
7
8
9
10

// Resource helper usage
this.resource("contacts")

// Shorthands defined
this.get("/contacts")
this.get("/contacts/:id")
this.post("/contacts")
this.patch("/contacts/:id") // and this.put('/contacts/:id')
this.del("/contacts/:id")

也可以指定一个白名单,以白名单为基础定义资源路由:

1
2
3
4
5
6
// 第二个参数中数组里必须传入有效的动作名称,完整的列表将在后面给出
this.resource("contacts", { only: ["index", "show"] })

// Shorthands defined
this.get("/contacts")
this.get("/contacts/:id")

或者指定一个排除列表,创建的资源路由中将不包含被排除的路由:

1
2
3
4
5
6
7
this.resource("contacts", { except: ["update"] })

// Shorthands defined
this.get("/contacts")
this.get("/contacts/:id")
this.post("/contacts")
this.del("/contacts/:id")

如果路由路径和集合名称不匹配,也可以指定一个相对或者绝对路径:

1
2
3
4
5
6
7
8
9
this.resource("blog-posts", { path: "/posts" })

// Shorthands defined
this.get("/posts", "blog-posts")
this.get("/posts/:id", "blog-posts")
this.post("/posts", "blog-posts")
this.put("/posts/:id", "blog-posts")
this.patch("/posts/:id", "blog-posts")
this.del("/posts/:id", "blog-posts")

下面是完整的可用于 only/except 选项的有效动作名称以及所表示的路由缩写:

1
2
3
4
5
6
7
Action   |  Shorthand
------------------------------
index | this.get('/contacts')
show | this.get('/contacts/:id')
create | this.post('/contacts')
update | this.patch('contacts/:id') (or this.put)
delete | this.del('/contacts/:id')
MirageJS Part 2 - Main Concepts - Route handlers

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×