真正的RESTful API利用超媒体,以便客户端仅依靠服务器提供的动态超媒体来浏览应用程序(称为HATEOAS的概念)
这个概念很容易适用于Web应用程序,但是如何将它应用于单页应用程序,因为SPA通常在内部管理其状态(在导航方面不依赖于服务器)?
我的感觉是SPA无法充分利用RESTful API,或者我错过了什么?
由于
Riana
答案 0 :(得分:5)
单页面应用程序(SPA)可以充分利用启用了HATEOAS的RESTful API,例如SPA(带有ui-rauter的angularJS用于状态转换)
对于计算机到计算机的交互,我们宣传协议 通过在表示中嵌入链接来实现信息 人类网络。
在消费者服务互动中: -
带示例代码的插图 服务入口点
var applicationServices = angular.module('applicationServices', ['ngResource']);
userDetailServices.factory('DetailService', ['$resource',function($resource){
return $resource('api/users', {},{
query : {
method : 'GET',
headers : {'Accept': 'application/json'},
isArray: true
}
});
}]);
超媒体是关于松散耦合,在开发服务时我们 通过减少耦合来抽象消费者的细节,但是 无论消费者必须拥有足够松散耦合的程度 可用信息以便与我们的服务进行交互
假设api/users
是服务的入口点,也是SPA知道的唯一网址,它将使用填充了进一步交互链接的资源表示进行响应。
{
"links": [
{
"rel": "self",
"href": "http://localhost:8080/persons{?page,size,sort}"
}
],
"users": [
{
"id": "3415NE11",
"firstName": "somefirstname",
"lastName": "lastname",
"emailAddress": "someemail",
"links": [
{
"rel": "section1",
"href": "http://localhost:8080/persons/3415NE11/section1
},
{
"rel": "section2",
"href": "http://localhost:8080/persons/3415NE11/section2
},
{
"rel": "gallery,
"href": "http://localhost:8080/filesRepo/profile/3415NE11/images
},
]
}
],
"page": {
"size": 20,
"totalElements": 2,
"totalPages": 1,
"number": 0
}
}
您的SPA从有关资源的部分信息开始,它将按需提供其他资源信息
使用ui-router导航
angular.module('userApp', [
'ui.bootstrap',
'ui.router',
'userControllers',
'userServices'
])
.config(
[ '$stateProvider', '$urlRouterProvider', '$httpProvider', function($stateProvider,$urlRouterProvider, $httpProvider) {
$stateProvider
.state('users', {
url: '/users-index',
templateUrl: 'partials/users-index.html',
resolve:{ // Your SPA needs this on start-up
DetailService:function(DetailService){
return DetailService.query();
}
},
controller:'UserController',
})
.state('users.section1', {
url: '/user-section1',
templateUrl: 'partials/user-section1.html',
})
.state('users.section2', {
url: '/users-section2',
templateUrl: 'partials/users.section2.html'
})
.state('users.gallery', {
url: '/users-gallery,
templateUrl: 'partials/users-gallery.html'
});
$urlRouterProvider.otherwise('/');
}])
.run([
'$rootScope',
'$location',
'$state',
'$stateParams'
function($rootScope, $location,$state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]);
angularJS SPA的UserController
(function() {
var userControllersApp = angular.module('userControllers', ['ngGeolocation']);
userControllersApp.controller('UserController',
['$scope',
'$rootScope',
'$http',
'$state',
'$filter',
'DetailService',
function($scope,$rootScope,$http,$state,$filter,DetailService) {
DetailService.$promise.then(function(result){
$scope.users = result.users;
});
$scope.userSection1= function(index){
var somelink = $filter('filter')($scope.users[index].links, { rel: "section1" })[0].href;
$http.get(somelink).success(function(data){
$state.go("users.section1");
});
// $http.post(somelink, data).success(successCallback);
};
$scope.userSection2= function(index){
var somelink = $filter('filter')($scope.users[index].links, { rel: "section2" })[0].href;
$http.get(somelink).success(function(data){
$state.go("users.section2");
});
// $http.post(somelink, data).success(successCallback);
};
$scope.userSection3= function(index){
var somelink = $filter('filter')($scope.users[index].links, { rel: "gallery" })[0].href;
$http.get(somelink).success(function(data){
$state.go("users.gallery");
});
// $http.post(somelink, data).success(successCallback);
};
} ]);
})();
超媒体的美妙之处在于它允许我们传达协议 信息以陈述性和恰到好处的方式作为一部分 应用程序的资源表示
使用$ scope.users嵌入式链接进行进一步的互动。了解somelink
,section1()
和section2()
函数中section(3)
的解析方式。
您的Angular SPA导航( users-index.html )可能是
<div ng-repeat="user in users">
<label>{{user.firstname}}</label>
<button type="button" class="btn btn-xs " ng-click="section1($index)">Section1</button>
<button type="button" class="btn btn-xs " ng-click="section2($index)">Section2</button>
<button type="button" class="btn btn-xs " ng-click="section3($index)">Section3</button>
</div>
现在,您的SPA状态转换依赖于服务器提供的动态链接来浏览应用程序,这表明SPA可以充分利用启用了HATEOAS的RESTful API。 my apologies for the very long explanation ,hope it helps.
答案 1 :(得分:2)
SPA的特殊之处在于它为客户端上构建的UI提供了更流畅的用户体验,而不是在服务器上构建并仅在客户端上呈现。
SPA不一定需要保持自己的状态,服务器仍然可以驱动与HATEOAS的交互。对于SPA是超媒体驱动或以其他方式维护自己的状态并访问预定义资源,完全取决于应用程序。
组合也可以起作用,例如SPA为某些部分维护自己的状态,而其他部分由服务器驱动。从这个意义上讲,考虑例如分页结果。 SPA可能会转到特定的URL(具有该资源的先验知识)以获取结果列表,并将这些结果分页。服务器在结果中嵌入链接,以便客户端可以将它们导航到下一页和上一页(您通过服务器提供的超媒体与应用程序交互)。
我的感觉是SPA无法充分利用RESTful API,或者我错过了什么?
正如我上面所说,这取决于你的申请。如果应用程序是超媒体驱动的,那么就可以像这样构建它。另一方面,如果让SPA“驱动自身”更有意义,那么强制使用HATEOS可能不是一个好主意。