Angular and HATEOAS

HATEOAS

HATEOAS (and Angular)

Coupling

The Richardson Maturity Model

Licence and registration

          GET /users/odysseus
          {
            "forename": "Odysseus",
            "surname": "Laertiades"
          }

          GET /users/odysseus/address
          {
            "houseName": "The palace",
            "city": "Ithaca"
          }
        

Licence and registration

          GET /users/odysseus
          {
            "forename": "Odysseus",
            "surname": "Laertiades"
          }

          GET /users/odysseus/address
          {
            "houseName": "The palace",
            "city": "Ithaca"
          }
        

Lvl: 3


          var apiRoot = 'http://api.example.com',
              apiMonarch = apiRoot + '/users/odysseus',
              apiAddress = apiMonarch + '/address';

          $http.get(apiMonarch).then(function(response) {
            $scope.monarch = response.data;
          });

          $http.get(apiAddress).then(function(response) {
            $scope.address = response.data;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

          var apiRoot = 'http://api.example.com',
              apiMonarch = apiRoot + '/users/odysseus',
              apiAddress = apiMonarch + '/address';

          $http.get(apiMonarch).then(function(response) {
            $scope.monarch = response.data;
          });

          $http.get(apiAddress).then(function(response) {
            $scope.address = response.data;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 1


          function userFactory(apiRoot, username) {
            var apiUser = apiRoot + '/users/' + username;
            return $http.get(apiUser).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(apiUser + '/address') ...
                }
              };
            });
          }

          userFactory(apiRoot, 'odysseus').then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

          function userFactory(apiRoot, username) {
            var apiUser = apiRoot + '/users/' + username;
            return $http.get(apiUser).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(apiUser + '/address') ...
                }
              };
            });
          }

          userFactory(apiRoot, 'odysseus').then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 1


          function userFactory(apiRoot, username) {
            var apiUser = apiRoot + '/users/' + username;
            return $http.get(apiUser).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(apiUser + '/address') ...
                }
              };
            });
          }

          userFactory(apiRoot, 'odysseus').then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 1

Hypermedia as the Engine of Application State

Licence; registration; family tree

          GET /
          {
            "_links": {
              "Monarch": "/users/odysseus"
            }
          }

          GET /users/odysseus
          {
            "forename": "Odysseus",
            "surname": "Laertiades",
            "_links": {
              "Address": "/users/odysseus/address",
              "Spouse": "/users/penelope"
            }
          }
        

Licence; registration; family tree

          GET /
          {
            "_links": {
              "Monarch": "/users/odysseus"
            }
          }

          GET /users/odysseus
          {
            "forename": "Odysseus",
            "surname": "Laertiades",
            "_links": {
              "Address": "/users/odysseus/address",
              "Spouse": "/users/penelope"
            }
          }
        

Lvl: 4


          function userFactory(apiRoot, username) {
            var apiUser = apiRoot + '/users/' + username;
            return $http.get(apiUser).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(apiUser + '/address') ...
                }
              };
            });
          }

          userFactory(apiRoot, 'odysseus').then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 1


          function monarchFactory(apiRoot) {
            return $http.get(apiRoot).then(function(response) {
              return $http.get(response._links.Monarch);
            }).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(response._links.Address) ...
                }
              };
            });
          }

          monarchFactory(apiRoot).then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

          function monarchFactory(apiRoot) {
            return $http.get(apiRoot).then(function(response) {
              return $http.get(response._links.Monarch);
            }).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(response._links.Address) ...
                }
              };
            });
          }

          monarchFactory(apiRoot).then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 4

Angular Ginsberg

I know too much and not enough

          function monarchFactory(apiRoot) {
            return $http.get(apiRoot).then(function(response) {
              return $http.get(response._links.Monarch);
            }).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(response._links.Address) ...
                }
              };
            });
          }

          monarchFactory(apiRoot).then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 4


          function monarchFactory(apiRoot) {
            return $http.get(apiRoot).then(function(response) {
              return $http.get(response._links.Monarch);
            }).then(function(response) {
              return {
                forename: response.data.forename,
                getAddress: function() {
                  ... $http.get(response._links.Address) ...
                }
              };
            });
          }

          monarchFactory(apiRoot).then(function(monarch) {
            $scope.monarch = monarch;
          });

          <em>{{ monarch.forename }}</em>
            lives in {{ address.city }}.
        

Lvl: 4


          $scope.response = $http.get(apiRoot);
          $scope.reactions = [
            {
              relation: 'Monarch',
              template: '<ng-monarch monarch="%response" />'
            }
          ];

          <ng-react to="response" with="reactions" />
        

          $scope.response = $http.get(apiRoot);
          $scope.reactions = [
            {
              relation: 'Monarch',
              template: '<ng-monarch monarch="%response" />'
            }
          ];

          <ng-react to="response" with="reactions" />
        

Lvl: 4

What's in a model?

And remember...


          TypeError: 'undefined' is not a function