AngularJS CRUD-Anwendung mit Spring Data REST

AngularJS CRUD-Anwendung mit Federdaten-REST

1. Überblick

In diesem Tutorial erstellen wir ein Beispiel für eine einfache CRUD-Anwendung mit AngularJS für das Front-End und Spring Data REST für das Back-End.

2. Erstellen des REST-Datendienstes

Um die Unterstützung für die Persistenz zu schaffen, verwenden wir die Spring Data REST-Spezifikation, mit der wir CRUD-Operationen an einem Datenmodell ausführen können.

Alle erforderlichen Informationen zum Einrichten der REST-Endpunkte finden Sie inintroduction to Spring Data REST. In diesem Artikel verwenden wir das vorhandene Projekt, das wir für das Einführungstutorial eingerichtet haben.

Für die Persistenz verwenden wirH2 in der Speicherdatenbank.

Als Datenmodell definiert der vorherige Artikel eineWebsiteUser-Klasse mit den Eigenschaftenid,name undemail und einer Repository-Schnittstelle namensUserRepository.

Durch das Definieren dieser Schnittstelle wird Spring angewiesen, die Unterstützung für das Offenlegen von REST-Auflistungs- und Elementressourcen zu erstellen. Schauen wir uns die Endpunkte genauer an, die uns jetzt zur Verfügung stehen, da wir später vonAngularJS aufrufen werden.

2.1. Die Sammlungsressourcen

Eine Liste aller Benutzer steht uns am Endpunkt/users zur Verfügung. Diese URL kann mit der GET-Methode aufgerufen werden und gibt JSON-Objekte der folgenden Form zurück:

{
  "_embedded" : {
    "users" : [ {
      "name" : "Bryan",
      "age" : 20,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users/1"
        },
        "User" : {
          "href" : "http://localhost:8080/users/1"
        }
      }
    },
...
    ]
  }
}

2.2. Die Artikelressourcen

Ein einzelnesWebsiteUser-Objekt kann manipuliert werden, indem mit verschiedenen HTTP-Methoden auf URLs der Form/users/{userID} zugegriffen und Nutzdaten angefordert werden.

Zum Abrufen einesWebsiteUser-Objekts können wir mit der GET-Methode auf/users/{userID} zugreifen. Dies gibt ein JSON-Objekt der Form zurück:

{
  "name" : "Bryan",
  "email" : "[email protected]",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/users/1"
    },
    "User" : {
      "href" : "http://localhost:8080/users/1"
    }
  }
}

Um ein neuesWebsiteUser hinzuzufügen, müssen wir/users mit der POST-Methode aufrufen. Die Attribute des neuenWebsiteUser-Datensatzes werden im Anforderungshauptteil als JSON-Objekt hinzugefügt:

{name: "Bryan", email: "[email protected]"}

Wenn keine Fehler vorliegen, gibt diese URL den Statuscode 201 CREATED zurück.

Wenn wir die Attribute des DatensatzesWebsiteUseraktualisieren möchten, müssen wir die URL/users/{UserID} mit der PATCH-Methode und einem Anforderungshauptteil aufrufen, der die neuen Werte enthält:

{name: "Bryan", email: "[email protected]"}

Um einenWebsiteUser-Datensatz zu löschen, können wir die URL/users/{UserID} mit der DELETE-Methode aufrufen. Wenn keine Fehler vorliegen, wird der Statuscode 204 NO CONTENT zurückgegeben.

2.3. MVC-Konfiguration

Wir werden auch eine grundlegende MVC-Konfiguration hinzufügen, um HTML-Dateien in unserer Anwendung anzuzeigen:

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

    public MvcConfig(){
        super();
    }

    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

2.4. Zulassen von Cross Origin-Anfragen

Wenn wir die Front-End-Anwendung vonAngularJSeparat als die REST-API bereitstellen möchten, müssen wir Cross-Origin-Anforderungen aktivieren.

Spring Data REST hat Unterstützung für diese ab Version 1.5.0.RELEASE hinzugefügt. Um Anforderungen von einer anderen Domäne zuzulassen, müssen Sie lediglich die Annotation@CrossOriginzum Repository hinzufügen:

@CrossOrigin
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository {}

Infolgedessen wird bei jeder Antwort von den REST-Endpunkten ein Header vonAccess-Control-Allow-Origin hinzugefügt.

3. Erstellen des AngularJS-Clients

Zum Erstellen des Frontends unserer CRUD-Anwendung verwenden wirAngularJS - ein bekanntes JavaScript-Framework, das die Erstellung von Front-End-Anwendungen vereinfacht.

UmAngularJS verwenden zu können, müssen wir zuerst die Dateiangular.min.js in unsere HTML-Seite aufnehmen, dieusers.html heißt:

Als Nächstes müssen Sie ein Angular-Modul, einen Controller und einen Service erstellen, der die REST-Endpunkte aufruft und die zurückgegebenen Daten anzeigt.

Diese werden in einer JavaScript-Datei mit dem Namenapp.js abgelegt, die auch auf der Seiteusers.html enthalten sein muss:

3.1. Winkelservice

Erstellen wir zunächst einen Angular-Dienst mit dem NamenUserCRUDService, der den injiziertenAngularJS$http-Dienst verwendet, um Anrufe an den Server zu tätigen. Jeder Anruf wird in einer separaten Methode getätigt.

Schauen wir uns an, wie Sie die Methode zum Abrufen eines Benutzers anhand der ID mithilfe des Endpunkts von/users/{userID}definieren:

app.service('UserCRUDService', [ '$http', function($http) {

    this.getUser = function getUser(userId) {
        return $http({
            method : 'GET',
            url : 'users/' + userId
        });
    }
} ]);

Definieren wir als Nächstes die MethodeaddUser, die eine POST-Anforderung an die URL/usersendet und die Benutzerwerte im Attributdata sendet:

this.addUser = function addUser(name, email) {
    return $http({
        method : 'POST',
        url : 'users',
        data : {
            name : name,
            email: email
        }
    });
}

DieupdateUser-Methode ähnelt der obigen, außer dass sie einenid-Parameter hat und eine PATCH-Anfrage stellt:

this.updateUser = function updateUser(id, name, email) {
    return $http({
        method : 'PATCH',
        url : 'users/' + id,
        data : {
            name : name,
            email: email
        }
    });
}

Die Methode zum Löschen einesWebsiteUser-Datensatzes führt eine DELETE-Anforderung aus:

this.deleteUser = function deleteUser(id) {
    return $http({
        method : 'DELETE',
        url : 'users/' + id
    })
}

Schauen wir uns zum Schluss die Methoden zum Abrufen der gesamten Benutzerliste an:

this.getAllUsers = function getAllUsers() {
    return $http({
        method : 'GET',
        url : 'users'
    });
}

Alle diese Dienstmethoden werden von einemAngularJS-Controller aufgerufen.

3.2. Winkelregler

Wir erstellen einenUserCRUDCtrlAngularJS-Controller, dem einUserCRUDService injiziert wird, und verwenden die Dienstmethoden, um die Antwort vom Server zu erhalten, und behandeln diesuccess underror) s Fälle und setzen Sie$scope Variablen, die die Antwortdaten für die Anzeige auf der HTML-Seite enthalten.

Werfen wir einen Blick auf die FunktiongetUser(), die die ServicefunktiongetUser(userId)aufruft und bei Erfolg und Fehler zwei Rückrufmethoden definiert. Wenn die Serveranforderung erfolgreich ist, wird die Antwort in eineruser-Variablen gespeichert. Andernfalls werden Fehlermeldungen behandelt:

app.controller('UserCRUDCtrl', ['$scope','UserCRUDService',
  function ($scope,UserCRUDService) {
      $scope.getUser = function () {
          var id = $scope.user.id;
          UserCRUDService.getUser($scope.user.id)
            .then(function success(response) {
                $scope.user = response.data;
                $scope.user.id = id;
                $scope.message='';
                $scope.errorMessage = '';
            },
            function error (response) {
                $scope.message = '';
                if (response.status === 404){
                    $scope.errorMessage = 'User not found!';
                }
                else {
                    $scope.errorMessage = "Error getting user!";
                }
            });
      };
}]);

Die FunktionaddUser()ruft die entsprechende Servicefunktion auf und verarbeitet die Antwort:

$scope.addUser = function () {
    if ($scope.user != null && $scope.user.name) {
        UserCRUDService.addUser($scope.user.name, $scope.user.email)
          .then (function success(response){
              $scope.message = 'User added!';
              $scope.errorMessage = '';
          },
          function error(response){
              $scope.errorMessage = 'Error adding user!';
              $scope.message = '';
        });
    }
    else {
        $scope.errorMessage = 'Please enter a name!';
        $scope.message = '';
    }
}

Die FunktionenupdateUser() unddeleteUser() ähneln denen oben:

$scope.updateUser = function () {
    UserCRUDService.updateUser($scope.user.id,
      $scope.user.name, $scope.user.email)
      .then(function success(response) {
          $scope.message = 'User data updated!';
          $scope.errorMessage = '';
      },
      function error(response) {
          $scope.errorMessage = 'Error updating user!';
          $scope.message = '';
      });
}

$scope.deleteUser = function () {
    UserCRUDService.deleteUser($scope.user.id)
      .then (function success(response) {
          $scope.message = 'User deleted!';
          $scope.User = null;
          $scope.errorMessage='';
      },
      function error(response) {
          $scope.errorMessage = 'Error deleting user!';
          $scope.message='';
      });
}

Definieren wir abschließend die Funktion, mit der eine Liste von Benutzern abgerufen und in der Variablenusersgespeichert wird:

$scope.getAllUsers = function () {
    UserCRUDService.getAllUsers()
      .then(function success(response) {
          $scope.users = response.data._embedded.users;
          $scope.message='';
          $scope.errorMessage = '';
      },
      function error (response) {
          $scope.message='';
          $scope.errorMessage = 'Error getting users!';
      });
}

3.3. HTML-Seite

Auf der Seiteusers.htmlwerden die im vorherigen Abschnitt definierten Steuerungsfunktionen und die gespeicherten Variablen verwendet.

Um das Angular-Modul verwenden zu können, müssen wir zunächst die Eigenschaftng-appfestlegen:

Um zu vermeiden, dassUserCRUDCtrl.getUser() jedes Mal eingegeben wird, wenn wir eine Funktion des Controllers verwenden, können wir unsere HTML-Elemente indiv mit dem Eigenschaftssatzng-controller einschließen:

Erstellen wir das_ form that will input and display the values for the _WebiteUser-Objekt, das wir bearbeiten möchten. Für jedes dieser Attribute wird einng-model-Attribut festgelegt, das es an den Wert des Attributs bindet:

ID:
Name:
Age:

Das Binden der Eingabe vonid an die Variableuser.idbedeutet beispielsweise, dass dieser Wert bei jeder Änderung des Eingabewerts in der Variablenuser.id festgelegt wird und umgekehrt.

Verwenden Sie als Nächstes das Attributng-click, um die Verknüpfungen zu definieren, die den Aufruf jeder definierten CRUD-Controller-Funktion auslösen:

Lassen Sie uns abschließend die Liste der Benutzer vollständig und nach Namen anzeigen:

Get all Users

{{usr.name}} {{usr.email}}

4. Fazit

In diesem Tutorial haben wir gezeigt, wie Sie eine CRUD-Anwendung mitAngularJS und derSpring Data REST-Spezifikation erstellen können.

Der vollständige Code für das obige Beispiel befindet sich inGitHub project.

Um die Anwendung auszuführen, können Sie den Befehlmvn spring-boot:run verwenden und auf die URL/users.html zugreifen.