首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >RESTful JSON API与Ember一起使用所需的约定

RESTful JSON API与Ember一起使用所需的约定
EN

Stack Overflow用户
提问于 2014-02-23 13:38:58
回答 1查看 12K关注 0票数 16

在Ember Models Introduction中,提到了:

在没有任何配置的情况下,

Data可以加载和保存通过Ember JSON API提供的记录及其关系,前提是它遵循某些约定。

我开始尝试使用基于令牌的RESTful JSON API,乍一看,它并不是严格意义上的RESTful。下面是几个例子:

  1. Authentication实现为接口返回状态为200 (response /api/authenticate?email=a@b.com&password=pass
  2. Most )的GET头部,即使失败也是如此。返回的json包含额外的字段success (boolean)和code (int),指示接口是否失败或通过。
  3. urls不是基于名词(模型)。例如,将典型的消息编辑操作实现为GET /api/edit_message?id=1&text=new

,该消息编辑操作传统上应该是对诸如/api/message/1/edit的url的投递

所以,我想知道是否有人可以列出文档中提到的这些certain conventions是什么。这可以帮助我理解是否可以使用ember-data。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-23 19:46:45

简而言之,EmberData可能不适合您的REST API,因为REST API并不是真正的rest API (它不使用HTTP动词,而是将操作作为查询字符串的一部分嵌入)。

为什么Ember Data可能不适合您

虽然Ember Data项目过去的目标可能是支持您正在描述的API,但最近,Ember Data开发人员明确表示,他们不打算将Ember Data与非传统API一起使用。例如,旨在“弥合鸿沟”并允许通过非传统REST使用Ember数据的BasicAdapter已被删除。

以下是Emberjs.com上的博客文章的实际引用和链接(值得一读):

"Ember Data现在将专注于成为Ember.js应用程序与一致的、传统的API进行通信的最佳库。“(http://emberjs.com/blog/2013/05/03/ember-data-progress-update.html)

正如这篇博文中所建议的,你应该看看下面的数据持久化库,它们可能更适合你的情况:

https://github.com/endlessinc/ember-restless

https://github.com/ebryn/ember-model

最后,您总是可以使用AJAX自己来做这件事,就像讨论人员做http://eviltrout.com/2013/03/23/ember-without-data.html一样

Authentication

据我所知,Ember Data不处理应用程序身份验证,我认为这就是您的示例所要表达的意思。对于您的身份验证系统,您可以考虑像Ember.SimpleAuth (https://github.com/simplabs/ember-simple-auth)这样的东西,它是高度可配置的,并且应该与您的身份验证机制一起工作(尽管它肯定需要编写一个自定义的验证器)。

编写一个自定义的Authenticator非常简单。

实际需要的Ember数据是什么

如果你还没有看过这个页面,我建议你仔细阅读一下:http://emberjs.com/guides/models/the-rest-adapter/

Ember数据将使用HTTP动词来传达意图。因此,当您在某个模型上调用createRecord并保存存储时,Ember Data将向您的REST API发出HTTP POST。当您尝试获取记录时,Ember将发出get请求。当你尝试删除一条记录时,Ember会发出一个delete请求(等等)。

假设您有三个模型,如下所示:

代码语言:javascript
复制
module.exports = App.ShoppingCart = DS.Model.extend({
    user: DS.belongsTo('user'), 
    items: DS.hasMany('item', {async:true}),
    name: attr('string'),
    enabled: attr('boolean')
});

module.exports = App.Item = DS.Model.extend({
    name: attr('string')
});

module.exports = App.User = DS.Model.extend({
   firstName: attr('string')
   lastName: attr('string')
});

当您尝试使用Ember加载记录时,this.store.find('shoppingCart', 1)将向模型名称的复数形式(在本例中为GET /shoppingCarts/1)发出GET请求。Ember内置了一系列规则来确定单词的复数形式,例如,它知道search的复数形式是searches而不是searchs。发出GET请求后,REST API需要返回以下JSON:

代码语言:javascript
复制
{
  "shoppingCart": {
      "id": 1,
      "name": "Bobs Shopping Cart",
      "user": 1, //this field links to the user with an id of 1
      "enabled": true,
      "items": [
        1,
        2
      ] 
    }
}

如果您正在执行this.store.find('shoppingCart'),那么Ember Data将发出一个GET /shoppingCarts,并期望返回一个以模型名称的复数形式为关键字的购物车对象数组。例如,如下所示:

代码语言:javascript
复制
{
  "shoppingCarts": [
     {
       "id": 1, //not specified in the model but must be sent by the REST API
       "name": "Bob's Shopping Cart",
       "user": 1, //this field links to the user with an id of 1
       "enabled": true,
       "items": [
         1,
         2
       ] 
     },
     {
       "id": 2, 
       "name": "John's Shopping Cart",
       "user": 2, //this field links to the user with an id of 2
       "enabled": false,
       "items": [
         3,  // these are ids for the item models
         4
       ] 
     }
  ]
}

请注意,当您从服务器返回记录时,您需要包括一个id字段,该字段唯一地标识所返回的记录。id字段不是在模型本身中指定的。当您创建一条新记录并将数据发送到服务器时,您不会包含id字段(因为它将在服务器端确定),但是REST API需要在响应中返回id是什么。

在上面的示例中,如果Ember Data在存储中缓存了用户" 1“,那么它将只使用该信息,否则它将向GET /users/1发出另一个GET请求,以检索用户1的信息。(如果您想避免多个GET请求,可以通过旁加载记录来提高效率)。

总而言之,惯例是使用HTTP动词来传达应该采取的操作,Ember Data将向其发送请求的URL基于您正在查询的模型名称的复数形式。

最大的警告:

我上面写的大部分内容都是基于这样的假设,即您希望在没有太多定制的情况下“开箱即用”使用Ember数据。一般来说,我认为当您能够控制REST API时,Ember Data最容易使用,并且可以对其进行调整,以符合Ember Data关于基于JSON的REST API应该如何工作的观点。更改Ember数据的默认行为是可能的,但我在尝试弯曲Ember数据以适应我的API方面经验不是很丰富,因此您可能需要从其他尝试过此操作的人那里获得一些输入。

票数 48
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21964664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档