Backbone.js RESTful API #
一、RESTful概述 #
1.1 REST原则 #
text
RESTful API设计原则
├── 资源导向:URL表示资源
├── HTTP方法:使用标准HTTP方法
├── 无状态:每个请求独立
└── 统一接口:一致的API设计
1.2 HTTP方法映射 #
| 操作 | HTTP方法 | URL | 说明 |
|---|---|---|---|
| Create | POST | /users | 创建资源 |
| Read | GET | /users/:id | 获取单个资源 |
| Read | GET | /users | 获取资源列表 |
| Update | PUT | /users/:id | 完整更新 |
| Update | PATCH | /users/:id | 部分更新 |
| Delete | DELETE | /users/:id | 删除资源 |
二、URL配置 #
2.1 urlRoot #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users'
});
var user = new User({ id: 1 });
console.log(user.url());
2.2 url方法 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users',
url: function() {
if (this.isNew()) {
return this.urlRoot;
}
return this.urlRoot + '/' + this.id;
}
});
2.3 集合URL #
javascript
var Users = Backbone.Collection.extend({
model: User,
url: '/api/users'
});
var users = new Users();
console.log(users.url);
2.4 动态URL #
javascript
var User = Backbone.Model.extend({
urlRoot: function() {
return '/api/' + this.get('type') + '/users';
}
});
var user = new User({ type: 'admin', id: 1 });
console.log(user.url());
2.5 嵌套资源URL #
javascript
var Comment = Backbone.Model.extend({
initialize: function(attrs, options) {
this.postId = options.postId;
},
urlRoot: function() {
return '/api/posts/' + this.postId + '/comments';
}
});
var comment = new Comment({ id: 1 }, { postId: 123 });
console.log(comment.url());
三、请求格式 #
3.1 默认请求格式 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users'
});
var user = new User();
user.save({ name: '张三', email: 'zhangsan@example.com' });
请求体:
json
{
"name": "张三",
"email": "zhangsan@example.com"
}
3.2 自定义请求头 #
javascript
user.save(attrs, {
headers: {
'X-Custom-Header': 'value',
'Accept': 'application/json'
}
});
3.3 自定义Content-Type #
javascript
Backbone.ajax = function(request) {
request.contentType = 'application/json';
return $.ajax(request);
};
3.4 发送前处理 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users',
sync: function(method, model, options) {
if (method === 'create' || method === 'update') {
options.data = JSON.stringify({
user: model.toJSON()
});
}
return Backbone.sync(method, model, options);
}
});
四、响应处理 #
4.1 parse方法 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users',
parse: function(response) {
return response.data || response;
}
});
4.2 处理嵌套数据 #
javascript
var User = Backbone.Model.extend({
parse: function(response) {
response.profile = new Profile(response.profile);
return response;
}
});
4.3 集合parse #
javascript
var Users = Backbone.Collection.extend({
url: '/api/users',
parse: function(response) {
this.total = response.total;
this.page = response.page;
return response.items;
}
});
4.4 处理分页 #
javascript
var Users = Backbone.Collection.extend({
url: '/api/users',
parse: function(response) {
this.pagination = {
total: response.total,
page: response.page,
perPage: response.per_page,
totalPages: response.total_pages
};
return response.data;
}
});
五、API示例 #
5.1 用户API #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users',
defaults: {
name: '',
email: '',
role: 'user'
},
validate: function(attrs) {
if (!attrs.name) return '姓名不能为空';
if (!attrs.email) return '邮箱不能为空';
},
parse: function(response) {
return response.user || response;
}
});
var Users = Backbone.Collection.extend({
model: User,
url: '/api/users',
parse: function(response) {
return response.users || response;
},
getActive: function() {
return this.filter(function(user) {
return user.get('active');
});
}
});
5.2 文章API #
javascript
var Post = Backbone.Model.extend({
urlRoot: '/api/posts',
defaults: {
title: '',
content: '',
author: null,
tags: [],
published: false
},
publish: function() {
this.save({ published: true }, {
url: this.url() + '/publish'
});
},
unpublish: function() {
this.save({ published: false }, {
url: this.url() + '/unpublish'
});
},
addComment: function(content) {
var self = this;
return $.ajax({
url: this.url() + '/comments',
method: 'POST',
data: JSON.stringify({ content: content }),
contentType: 'application/json'
});
}
});
5.3 搜索API #
javascript
var SearchCollection = Backbone.Collection.extend({
url: '/api/search',
search: function(query, options) {
options = options || {};
options.data = { q: query };
return this.fetch(options);
},
parse: function(response) {
this.query = response.query;
this.total = response.total;
return response.results;
}
});
var searchResults = new SearchCollection();
searchResults.search('backbone').then(function() {
console.log('找到', searchResults.total, '条结果');
});
六、错误处理 #
6.1 全局错误处理 #
javascript
$(document).ajaxError(function(event, xhr, settings, error) {
if (xhr.status === 401) {
console.log('未授权,请登录');
} else if (xhr.status === 403) {
console.log('禁止访问');
} else if (xhr.status === 404) {
console.log('资源不存在');
} else if (xhr.status >= 500) {
console.log('服务器错误');
}
});
6.2 模型错误处理 #
javascript
user.save(attrs, {
success: function(model, response) {
console.log('保存成功');
},
error: function(model, xhr) {
if (xhr.status === 422) {
var errors = xhr.responseJSON.errors;
console.log('验证错误:', errors);
}
}
});
6.3 错误事件 #
javascript
user.on('error', function(model, xhr) {
console.log('请求失败:', xhr.status);
});
user.fetch();
七、实用示例 #
7.1 API客户端 #
javascript
var APIClient = {
baseUrl: '/api',
request: function(method, path, data) {
return $.ajax({
url: this.baseUrl + path,
method: method,
data: data ? JSON.stringify(data) : null,
contentType: 'application/json',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
});
},
get: function(path) {
return this.request('GET', path);
},
post: function(path, data) {
return this.request('POST', path, data);
},
put: function(path, data) {
return this.request('PUT', path, data);
},
patch: function(path, data) {
return this.request('PATCH', path, data);
},
delete: function(path) {
return this.request('DELETE', path);
}
};
var User = Backbone.Model.extend({
sync: function(method, model, options) {
var path = model.isNew() ? '/users' : '/users/' + model.id;
switch (method) {
case 'read':
return APIClient.get(path);
case 'create':
return APIClient.post('/users', model.toJSON());
case 'update':
return APIClient.put(path, model.toJSON());
case 'patch':
return APIClient.patch(path, options.attrs || model.changedAttributes());
case 'delete':
return APIClient.delete(path);
}
}
});
7.2 分页API #
javascript
var PagedCollection = Backbone.Collection.extend({
initialize: function(models, options) {
this.page = 1;
this.perPage = options && options.perPage || 20;
this.total = 0;
},
fetchPage: function(page, options) {
options = options || {};
options.data = _.extend(options.data || {}, {
page: page,
per_page: this.perPage
});
var self = this;
return this.fetch(options).done(function() {
self.page = page;
});
},
parse: function(response) {
this.total = response.total;
this.totalPages = response.total_pages;
return response.data;
},
hasNextPage: function() {
return this.page < this.totalPages;
},
hasPrevPage: function() {
return this.page > 1;
},
nextPage: function() {
if (this.hasNextPage()) {
return this.fetchPage(this.page + 1);
}
},
prevPage: function() {
if (this.hasPrevPage()) {
return this.fetchPage(this.page - 1);
}
}
});
八、总结 #
8.1 URL配置 #
| 属性/方法 | 说明 |
|---|---|
| urlRoot | 模型URL根路径 |
| url | 集合URL |
| url() | 动态生成URL |
8.2 最佳实践 #
- 使用RESTful API设计
- 合理配置URL
- 使用parse处理响应
- 统一错误处理
- 封装API客户端
最后更新:2026-03-28