我正在开发一个Ember应用程序,该应用程序聚合来自Facebook的Graph API和Rails API的内容。由于我编写了Rails API并且可以控制JSON格式,因此我在使用Ember应用程序查询和提供该内容时没有任何问题。但是,我在规范Facebook Graph API内容方面遇到了一些困难。
举个例子,这是Facebook API提供的一些Feed JSON:
{
"data": [
{
"id": "604231966385537_765079483634117",
"type": "link",
"message": "They're watching you...",
"from": {
"name": "Kristian Twombly",
"id": "10154089935544635"
}
},
{
"id": "604231966385537_765057943636271",
"type": "status",
"message": "The boss's new ride. He saw mine and had to have one.",
"from": {
"name": "Walter Johnson",
"id": "10206908914060788"
}
},
{
"id": "604231966385537_764751447000254",
"type": "photo",
"message": "Found 1 at Target Apple Valley",
"from": {
"name": "Quentin Waterkamp",
"id": "10210042929332132"
},
"comments": {
"data": [
{
"created_time": "2016-09-01T01:33:55+0000",
"from": {
"name": "Riley Richardson",
"id": "1189835384423610"
},
"message": "Are these rare to find or something?",
"id": "764829800325752"
},
{
"created_time": "2016-09-01T04:33:44+0000",
"from": {
"name": "Quentin Waterkamp",
"id": "10210042929332132"
},
"message": "seems to be I was also at a Walmart today and didn't see one and the other Target in Apple Valley didn't have any the other day.",
"id": "764893193652746"
}
],
"paging": {
"cursors": {
"before": "WTI5dGJXVnVkRjlqZAFhKemIzSTZAOelkwT0RJNU9EQXdNekkxTnpVeU9qRTBOekkyT1RNMk16VT0ZD",
"after": "WTI5dGJXVnVkRjlqZAFhKemIzSTZAOelkwT0Rrek1Ua3pOalV5TnpRMk9qRTBOekkzTURRME1qUT0ZD"
}
}
},
}
],
"paging": {
"previous": "https://graph.facebook.com/v2.7/604231966385537/feed?fields=id,type,message,from,comments&icon_size=16&since=1472731871&access_token=1333570303337296|ssnHtq9p3DuFAxX23XRx7Dc1reQ&limit=25&__paging_token=enc_AdBfsb6FAxWTzuRVAHs3OujbQ3O0Ry2z7QIHq40E45FaLZAyf2mYy888ZASAEiw7D0N31xuAij5ZBsYVZBeVPZAXz5HfDAN2ZAklhsRHRjMu7qLzdODgZDZD&__previous=1",
"next": "https://graph.facebook.com/v2.7/604231966385537/feed?fields=id,type,message,from,comments&icon_size=16&access_token=1333570303337296|ssnHtq9p3DuFAxX23XRx7Dc1reQ&limit=25&until=1472348927&__paging_token=enc_AdBhRIcyqcv8ZByyC5GnCv2PfoIzySxiZCSdRw3LoOCE2gj51ZCMv9l7OPGWLcrJeHal9Tna2rhsGEul5jEzN93dBA1BXhzdgZCmOOT9y8OqDZCSh2wZDZD"
}
}
鉴于根元素是data
,我最初认为它是在JSON API规范中提供的。但是,缺少attributes
键意味着默认的Ember JSONAPISerializer在没有一些修改的情况下不起作用。相反,data
键的存在意味着JSONSerializer也无法正确解析JSON。
我没有幸运获得JSON为所有对象正确序列化。如果我删除comments
上的/app/models/facebook-photo.js
属性,我可以填充顶层对象(如照片,链接,状态)(我在Chrome中使用Ember Inspector确认了这一点)。但是,我无法序列化hasMany
的嵌入式comments
关系。当我尝试运行我的Ember应用程序时,我当前收到以下错误:
extractembeddedhasmany无法读取null
的属性'id'
任何人都可以帮助我了解如何从Facebook API正确规范化JSON吗?此外,如何正确配置hasMany
的{{1}}关系?
作为参考,这是我的最新代码(我只包含了comments
的代码以进行简化):
请注意:我已经使用了facebook-photo
和modelNameFromPayloadKey
序列化程序方法,因为我的Facebook API模型在类型名称后附加了“facebook-”(模型名称与我的冲突)其他API的类型)。
/app/routes/index.js
payloadKeyFromModelName
/app/adapters/facebook-feed.js:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.RSVP.hash({
facebookFeedObjects: this.get('store').query('facebook-feed', {
fields: 'id,type,message,from,comments',
access_token: '1333570303337296%7CssnHtq9p3DuFAxX23XRx7Dc1reQ'
})
});
}
});
/app/models/facebook-photo.js:
import Ember from 'ember';
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'https://graph.facebook.com/v2.7',
namespace: '604231966385537',
pathForType: function(type) {
return 'feed';
}
});
/app/serializers/facebook-feed.js:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
export default Model.extend({
message: attr(),
comments: hasMany('facebook-comment', { polymorphic: true })
});
/app/serializers/facebook-photo.js:
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
modelNameFromPayloadKey(key) {
let withPrefix = 'facebook-' + key;
return this._super(withPrefix);
},
payloadKeyFromModelName(modelName) {
let type = this._super(modelName);
return `${type.replace('facebook-', '')}`;
}
});
/app/templates/index.hbs:
import DS from 'ember-data';
export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
modelNameFromPayloadKey(key) {
let withPrefix = 'facebook-' + key;
return this._super(withPrefix);
},
payloadKeyFromModelName(modelName) {
let type = this._super(modelName);
return `${type.replace('facebook-', '')}`;
},
attrs: {
comments: { embedded: 'always' }
}
});
答案 0 :(得分:1)
我认为你最好的选择就是写下own custom serializer。类似的东西:
export default DS.JSONAPISerializer.extend({
serialize(snapshot, options) {
var json = this._super(...arguments);
json.data.attributes.message = json.data.message;
json.data.attributes.from = {
name: json.data.from.name,
id: json.data.from.id
}
delete json.data.message;
delete json.data.from
return json;
},
});
请注意,这不会考虑评论字段,但您应该可以执行类似的操作来构建关系以遵守JSON API format。