Одностраничное приложение и RESTful API
Реальный RESTful API использует гипермедиа, так что клиенты полагаются только на динамические гипермедиа, предоставляемые сервером для навигации по приложению (концепция, известная как HATEOAS)
Эта концепция легко применима к веб-приложениям, но как применить ее к Одностраничному приложению, поскольку Spa обычно управляют своим состоянием внутренне (не полагаясь на сервер в том, что касается навигации) ?
Мое ощущение таково, что Спа не могут полностью использовать RESTful APIs или я что-то пропустил ?
Спасибо
Риана
2 ответа:
Особенность SPA заключается в том, что он обеспечивает более гибкий пользовательский интерфейс, построенный на клиенте, вместо того, чтобы быть построенным на сервере и просто визуализироваться на клиенте.
SPA не обязательно должен поддерживать свое собственное состояние, сервер все еще может управлять взаимодействиями с HATEOAS. Для спа, чтобы быть управляемым гипермедиа или иным образом поддерживать свое собственное состояние и доступ к предопределенным ресурсам, полностью зависит от приложения.
Комбинации также могут работать, как например, SPA поддерживает свое собственное состояние для некоторых частей, а другие управляются сервером. В этом смысле рассмотрим, например, результаты разбиения на страницы. Спа-центр может перейти на определенный URL-адрес (предварительно зная об этом ресурсе), чтобы получить список результатов, причем эти результаты будут разбиты на страницы. Сервер вставляет ссылки внутрь результатов, чтобы клиент мог перейти по ним на следующую и предыдущую страницы (вы взаимодействуете с приложением через гипермедиа, предоставляемые сервером).
Мне кажется, что SPAs не может полностью использовать RESTful APIs, или я что-то упустил ?
Как я сказал выше, это зависит от вашего приложения. Если это имеет смысл для приложения, управляемого гипермедиа, то его можно построить таким образом. С другой стороны, если это имеет больше смысла, чтобы СПА "приводил себя в движение", то принуждение HATEO к нему может быть не очень хорошей идеей.
Одностраничные приложения (SPA) могут полностью использовать RESTful API, которые включены HATEOAS, например SPA (angularJS с ui-rauter для перехода в состояние)
Для взаимодействия компьютера с компьютером мы рекламируем протоколы информация путем встраивания ссылок в представление во многом так же, как мы это делаем в человеческая паутина.
Во взаимодействии потребителя и сервиса: -
- потребитель подает первоначальный запрос в точку входа обслуживание.
- в служба обрабатывает запрос и отвечает представлением ресурса, заполненным ссылками.
Потребитель выбирает одно из звеньев для перехода к следующему шагу. во взаимодействии. Над причиной нескольких таких взаимодействий потребительский прогресс к своей цели.Иллюстрация с образцом кода Служебная Точка Входа
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
является точкой входа в сервис и единственным url-адресом,о котором знает ваш Спа, он ответит представлением ресурса, заполненным ссылками для дальнейшего взаимодействия.{ "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 } }
Ваш спа-центр начинается с частичной информации о ресурсе, и он будет подавать дополнительную информацию о ресурсах по требованию
- список пользователей с неполной информацией о пользователе (при запуске, знает url перед рукой)
- Раздел 1 информации о ресурсах пользователя (по запросу, поиск url из 1 выше)
- Раздел 2 информации о ресурсах пользователя (по запросу, поиск url из 1 выше)
- раздел-n информации о ресурсах пользователя (по запросу, смотрите url от 1 выше)
С навигацией ui-маршрутизатора
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; } ]);
UserController для вашего спа angularJS
(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.пользователи встраивают ссылки для дальнейшего взаимодействия.посмотрите, как
somelink
решается вsection1()
,section2()
иsection(3)
функции.Ваш угловой СПА-навигатор (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 в свою очередь полагается на динамические ссылки,предоставляемые сервером для навигации по приложению, это показывает, что SPAs может полностью использовать HATEOAS enabled RESTful API.
my apologies for the very long explanation ,hope it helps.