Applicazione AngularJS CRUD con Spring Data REST

1. Panoramica

In questo tutorial creeremo un esempio di una semplice applicazione CRUD utilizzando AngularJS per il front-end e Spring Data REST per il back-end.

2. Creazione del servizio dati REST

Per creare il supporto per la persistenza, utilizzeremo la specifica REST di Spring Data che ci consentirà di eseguire operazioni CRUD su un modello di dati.

Puoi trovare tutte le informazioni necessarie su come configurare gli endpoint REST nell'introduzione a Spring Data REST. In questo articolo, riutilizzeremo il progetto esistente che abbiamo impostato per il tutorial introduttivo.

Per la persistenza, useremo H2 nel database di memoria.

Come modello di dati, l'articolo precedente definisce una classe WebsiteUser , con id , nome e proprietà di posta elettronica e un'interfaccia di repository chiamata UserRepository .

La definizione di questa interfaccia indica a Spring di creare il supporto per l'esposizione delle risorse della raccolta REST e delle risorse degli elementi. Diamo uno sguardo più da vicino agli endpoint a nostra disposizione ora che chiameremo in seguito da AngularJS .

2.1. Le risorse della raccolta

Un elenco di tutti gli utenti sarà disponibile all'endpoint / utenti . Questo URL può essere chiamato utilizzando il metodo GET e restituirà oggetti JSON del modulo:

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

2.2. Le risorse dell'articolo

Un singolo oggetto WebsiteUser può essere manipolato accedendo agli URL del modulo / users / {userID} con diversi metodi HTTP e richieste di payload.

Per recuperare un oggetto WebsiteUser , possiamo accedere a / users / {userID} con il metodo GET. Questo restituisce un oggetto JSON del modulo:

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

Per aggiungere un nuovo WebsiteUser , dovremo chiamare / users con il metodo POST. Gli attributi del nuovo record WebsiteUser verranno aggiunti nel corpo della richiesta come oggetto JSON:

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

Se non sono presenti errori, questo URL restituisce un codice di stato 201 CREATO.

Se vogliamo aggiornare gli attributi del record WebsiteUser , dobbiamo chiamare l'URL / users / {UserID} con il metodo PATCH e un corpo della richiesta contenente i nuovi valori:

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

Per eliminare un record WebsiteUser , possiamo chiamare l'URL / users / {UserID} con il metodo DELETE. Se non sono presenti errori, restituisce il codice di stato 204 NESSUN CONTENUTO.

2.3. Configurazione MVC

Aggiungeremo anche una configurazione MVC di base per visualizzare i file html nella nostra applicazione:

@Configuration @EnableWebMvc public class MvcConfig implements WebMvcConfigurer { public MvcConfig(){ super(); } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }

2.4. Consentire richieste di origine incrociata

Se vogliamo distribuire l' applicazione front-end AngularJS separatamente dall'API REST, dobbiamo abilitare le richieste cross-origin.

Spring Data REST ha aggiunto il supporto per questo a partire dalla versione 1.5.0.RELEASE. Per consentire le richieste da un dominio diverso, tutto ciò che devi fare è aggiungere l' annotazione @CrossOrigin al repository:

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

Di conseguenza, su ogni risposta dagli endpoint REST, verrà aggiunta un'intestazione di Access-Control-Allow-Origin .

3. Creazione del client AngularJS

Per creare il front-end della nostra applicazione CRUD, useremo AngularJS , un noto framework JavaScript che facilita la creazione di applicazioni front-end.

Per poter utilizzare AngularJS , dobbiamo prima includere il file angular.min.js nella nostra pagina html che si chiamerà users.html :

Next, we need to create an Angular module, controller, and service that will call the REST endpoints and display the returned data.

These will be placed in a JavaScript file called app.js that also needs to be included in the users.html page:

3.1. Angular Service

First, let's create an Angular service called UserCRUDService that will make use of the injected AngularJS$http service to make calls to the server. Each call will be placed in a separate method.

Let's take a look at defining the method for retrieving a user by id using the /users/{userID} endpoint:

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

Next, let's define the addUser method which makes a POST request to the /users URL and sends the user values in the data attribute:

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

The updateUser method is similar to the one above, except it will have an id parameter and makes a PATCH request:

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

The method for deleting a WebsiteUser record will make a DELETE request:

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

And finally, let's take a look at the methods for retrieving the entire list of users:

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

All of these service methods will be called by an AngularJS controller.

3.2. Angular Controller

We will create an UserCRUDCtrlAngularJS controller that will have an UserCRUDService injected and will use the service methods to obtain the response from the server, handle the success and error cases, and set $scope variables containing the response data for displaying it in the HTML page.

Let's take a look at the getUser() function that calls the getUser(userId) service function and defines two callback methods in case of success and error. If the server request succeeds, then the response is saved in a user variable; otherwise, error messages are handled:

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!"; } }); }; }]);

The addUser() function will call the corresponding service function and handle the response:

$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 = ''; } }

The updateUser() and deleteUser() functions are similar to the one above:

$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=''; }); }

And finally, let's define the function that retrieves a list of users, and stores it in the users variable:

$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 Page

The users.html page will make use of the controller functions defined in the previous section and the stored variables.

First, in order to use the Angular module, we need to set the ng-app property:

Then, to avoid typing UserCRUDCtrl.getUser() every time we use a function of the controller, we can wrap our HTML elements in a div with a ng-controller property set:

Let's create theform that will input and display the values for the WebiteUser object we want to manipulate. Each of these will have a ng-model attribute set, which binds it to the value of the attribute:


    
ID:
Name:
Age:

Binding the id input to the user.id variable, for example, means that whenever the value of the input is changed, this value is set in the user.id variable and vice versa.

Successivamente, utilizziamo l' attributo ng-click per definire i collegamenti che attiveranno l'invocazione di ciascuna funzione del controller CRUD definita:

Get User Update User Add User Delete User

Infine, mostriamo l'elenco degli utenti interamente e per nome:

Get all Users

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

4. Conclusione

In questo tutorial, abbiamo mostrato come creare un'applicazione CRUD utilizzando AngularJS e la specifica REST di Spring Data .

Il codice completo per l'esempio precedente può essere trovato nel progetto GitHub.

Per eseguire l'applicazione, puoi utilizzare il comando mvn spring-boot: esegui e accedi all'URL /users.html .