Utiliser Spring Data R2DBC avec Azure SQL Database

Cet article décrit la création d’un exemple d’application qui utilise Spring Data R2DBC pour stocker et récupérer des informations dans Azure SQL Database en utilisant l’implémentation R2DBC pour Microsoft SQL Server du dépôt GitHub r2dbc-mssql.

R2DBC permet d’utiliser des API réactives avec les bases de données relationnelles classiques. Vous pouvez l’utiliser avec Spring WebFlux pour créer des applications Spring Boot entièrement réactives qui utilisent des API non bloquantes. Il offre une meilleure scalabilité que l’approche classique « un thread par connexion ».

Prérequis

  • utilitaire sqlcmd.

  • cURL ou un utilitaire HTTP similaire pour tester la fonctionnalité.

Voir l’exemple d’application

Dans cet article, vous allez coder un exemple d’application. Si vous souhaitez aller plus vite, cette application est déjà codée et disponible sur https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-sql-server.

Préparer l’environnement de travail

Tout d’abord, configurez des variables d’environnement à l’aide des commandes suivantes :

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_SQL_SERVER_ADMIN_USERNAME=spring
export AZ_SQL_SERVER_ADMIN_PASSWORD=<YOUR_AZURE_SQL_ADMIN_PASSWORD>
export AZ_SQL_SERVER_NON_ADMIN_USERNAME=nonspring
export AZ_SQL_SERVER_NON_ADMIN_PASSWORD=<YOUR_AZURE_SQL_NON_ADMIN_PASSWORD>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>

Remplacez les espaces réservés par les valeurs suivantes, qui sont utilisées dans cet article :

  • <YOUR_DATABASE_NAME>: nom de votre serveur Azure SQL Database, qui doit être unique sur Azure.
  • <YOUR_AZURE_REGION>: région Azure que vous allez utiliser. Vous pouvez utiliser eastus par défaut, mais nous vous recommandons de configurer une région plus proche de l’endroit où vous vivez. Vous pouvez voir la liste complète des régions disponibles à l’aide az account list-locationsde .
  • <AZ_SQL_SERVER_ADMIN_PASSWORD> et <AZ_SQL_SERVER_NON_ADMIN_PASSWORD>: mot de passe de votre serveur Azure SQL Database, qui doit comporter au moins huit caractères. Il doit contenir des caractères de trois des catégories suivantes : Lettres majuscules, lettres minuscules, chiffres (0-9) et caractères non alphanumériques (comme !, $, #, %, etc.).
  • <YOUR_LOCAL_IP_ADDRESS>: adresse IP de votre ordinateur local, à partir duquel vous exécuterez l’application Spring Boot. Un moyen pratique de le trouver est d’ouvrir whatismyip.akamai.com.

Ensuite, créez un groupe de ressources à l’aide de la commande suivante :

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION \
    --output tsv

Créer une instance Azure SQL Database

Ensuite, créez une instance de serveur Azure SQL Database managée en exécutant la commande suivante.

Remarque

Le mot de passe MS SQL doit répondre à des critères spécifiques et le programme d’installation échoue avec un mot de passe non conforme. Pour plus d'informations, consultez Password Policy.

az sql server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --admin-user $AZ_SQL_SERVER_ADMIN_USERNAME \
    --admin-password $AZ_SQL_SERVER_ADMIN_PASSWORD \
    --output tsv

Configurer une règle de pare-feu pour votre serveur Azure SQL Database

Les instances Azure SQL Database sont sécurisées par défaut. Elles ont un pare-feu qui n’autorise aucune connexion entrante. Pour pouvoir utiliser notre base de données, vous devez ajouter une règle de pare-feu qui permet à l’adresse IP locale d’accéder au serveur de base de données.

Comme vous avez configuré votre adresse IP locale au début de cet article, vous pouvez ouvrir le pare-feu du serveur en exécutant la commande suivante :

az sql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    --output tsv

Si vous vous connectez à votre serveur Azure SQL Database à partir de Sous-système Windows pour Linux (WSL) sur un ordinateur Windows, vous devez ajouter l’ID d’hôte WSL à votre pare-feu.

Obtenez l’adresse IP de votre ordinateur hôte en exécutant la commande suivante dans WSL :

cat /etc/resolv.conf

Copiez l’adresse IP suivant le terme nameserver, puis utilisez la commande suivante pour définir une variable d’environnement pour l’adresse IP de WSL :

export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Ensuite, utilisez la commande suivante pour ouvrir le pare-feu du serveur sur votre application WSL :


az sql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip-wsl \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

Configurer une base de données Azure SQL

Le serveur Azure SQL Database que vous avez créé précédemment est vide. Il ne contient aucune base de données que vous pouvez utiliser avec l’application Spring Boot. Créez une base de données nommée demo en exécutant la commande suivante :

az sql db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name demo \
    --server $AZ_DATABASE_NAME \
    --output tsv

Créer un utilisateur non administrateur de base de données SQL et accorder une autorisation

Cette étape crée un utilisateur non administrateur et lui accorde toutes les autorisations sur la demo base de données.

Créez un script SQL appelé create_user.sql pour créer un utilisateur non administrateur. Ajoutez le contenu suivant et enregistrez-le localement :

cat << EOF > create_user.sql
USE demo;
GO
CREATE USER $AZ_SQL_SERVER_NON_ADMIN_USERNAME WITH PASSWORD='$AZ_SQL_SERVER_NON_ADMIN_PASSWORD'
GO
GRANT CONTROL ON DATABASE::demo TO $AZ_SQL_SERVER_NON_ADMIN_USERNAME;
GO
EOF

Ensuite, utilisez la commande suivante pour exécuter le script SQL pour créer l’utilisateur non administrateur :

sqlcmd -S $AZ_DATABASE_NAME.database.windows.net,1433  -d demo -U $AZ_SQL_SERVER_ADMIN_USERNAME -P $AZ_SQL_SERVER_ADMIN_PASSWORD  -i create_user.sql

Remarque

Pour plus d’informations sur la création d’utilisateurs de base de données SQL, consultez CREATE USER (Transact-SQL).


Créer une application Spring Boot réactive

Pour créer une application Spring Boot réactive, nous allons utiliser Spring Initializr. L’application que nous allons créer utilise :

  • Spring Boot 2.7.11.
  • Les dépendances suivantes : Spring React Web (également appelé Spring WebFlux) et Spring Data R2DBC.

Générer l’application à l’aide de Spring Initializr

Générez l’application sur la ligne de commande en exécutant la commande suivante :

curl https://start.spring.io/starter.tgz -d dependencies=webflux,data-r2dbc -d baseDir=azure-database-workshop -d bootVersion=2.7.11 -d javaVersion=17 | tar -xzvf -

Ajouter l’implémentation du pilote Azure SQL Database réactif

Ouvrez le fichier pom.xml du projet généré pour ajouter le pilote Azure SQL Database réactif à partir du dépôt GitHub r2dbc-mssql.

Après la dépendance spring-boot-starter-webflux, ajoutez le texte suivant :

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-mssql</artifactId>
    <scope>runtime</scope>
</dependency>

Configurer Spring Boot pour qu’il utilise Azure SQL Database

Ouvrez le fichier src/main/resources/application.properties et ajoutez le texte suivant :

logging.level.org.springframework.data.r2dbc=DEBUG

spring.r2dbc.url=r2dbc:pool:mssql://$AZ_DATABASE_NAME.database.windows.net:1433/demo
spring.r2dbc.username=nonspring@$AZ_DATABASE_NAME
spring.r2dbc.password=$AZ_SQL_SERVER_NON_ADMIN_PASSWORD

Remplacez les deux variables $AZ_DATABASE_NAME et la variable $AZ_SQL_SERVER_NON_ADMIN_PASSWORD par les valeurs que vous avez configurées au début de cet article.

Remarque

Pour de meilleures performances, la propriété spring.r2dbc.url est configurée de manière à utiliser un pool de connexions avec r2dbc-pool.

Vous devez maintenant être en mesure de démarrer votre application à l’aide du wrapper Maven fourni comme suit :

./mvnw spring-boot:run

Voici une capture d’écran de l’application s’exécutant pour la première fois :

Screenshot of the running application.

Créer le schéma de la base de données

Dans la classe principale DemoApplication, configurez un nouveau bean Spring qui créera le schéma de base de données, à l’aide du code suivant :

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.r2dbc.connectionfactory.init.ConnectionFactoryInitializer;
import org.springframework.data.r2dbc.connectionfactory.init.ResourceDatabasePopulator;

import io.r2dbc.spi.ConnectionFactory;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
        ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
        initializer.setConnectionFactory(connectionFactory);
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator(new ClassPathResource("schema.sql"));
        initializer.setDatabasePopulator(populator);
        return initializer;
    }
}

Ce bean Spring utilise un fichier nommé schema.sql. Créez ce fichier dans le dossier src/main/resources et ajoutez le texte suivant :

DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id INT IDENTITY PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BIT);

Arrêtez l’application en cours d’exécution, puis redémarrez-la à l’aide de la commande suivante. L’application utilise désormais la base de données demo que vous avez créée précédemment et crée une table todo dans cette base de données.

./mvnw spring-boot:run

Voici une capture d’écran de la table de base de données en cours de création :

Screenshot of the creation of the database table.

Coder l’application

Ensuite, ajoutez le code Java qui utilisera R2DBC pour stocker et récupérer des données à partir de votre serveur Azure SQL Database.

Créez une classe Java Todo parallèlement à la classe DemoApplication en utilisant le code suivant :

package com.example.demo;

import org.springframework.data.annotation.Id;

public class Todo {

    public Todo() {
    }

    public Todo(String description, String details, boolean done) {
        this.description = description;
        this.details = details;
        this.done = done;
    }

    @Id
    private Long id;

    private String description;

    private String details;

    private boolean done;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public boolean isDone() {
        return done;
    }

    public void setDone(boolean done) {
        this.done = done;
    }
}

Cette classe est un modèle de domaine mappé sur la table todo que vous avez créée précédemment.

Pour gérer cette classe, vous avez besoin d’un référentiel. Définissez une nouvelle interface TodoRepository dans le même package en utilisant le code suivant :

package com.example.demo;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

public interface TodoRepository extends ReactiveCrudRepository<Todo, Long> {
}

Ce dépôt est un dépôt réactif géré par Spring Data R2DBC.

Terminez l’application en créant un contrôleur pouvant stocker et récupérer des données. Implémentez une classe TodoController dans le même package, puis ajoutez le code suivant :

package com.example.demo;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/")
public class TodoController {

    private final TodoRepository todoRepository;

    public TodoController(TodoRepository todoRepository) {
        this.todoRepository = todoRepository;
    }

    @PostMapping("/")
    @ResponseStatus(HttpStatus.CREATED)
    public Mono<Todo> createTodo(@RequestBody Todo todo) {
        return todoRepository.save(todo);
    }

    @GetMapping("/")
    public Flux<Todo> getTodos() {
        return todoRepository.findAll();
    }
}

Pour finir, arrêtez l’application et redémarrez-la à l’aide de la commande suivante :

./mvnw spring-boot:run

Test de l’application

Pour tester l’application, vous pouvez utiliser cURL.

Tout d’abord, créez un élément « todo » dans la base de données à l’aide de la commande suivante :

curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done": "true"}' \
    http://127.0.0.1:8080

Cette commande doit retourner l’élément créé, comme illustré ici :

{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}

Ensuite, récupérez les données à l’aide d’une nouvelle requête cURL avec la commande suivante :

curl http://127.0.0.1:8080

Cette commande retourne la liste des éléments « todo », y compris celui que vous avez créé, comme illustré ici :

[{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}]

Voici une capture d’écran de ces requêtes cURL :

Screenshot of the cURL test.

Félicitations ! Vous avez créé une application Spring Boot entièrement réactive, qui utilise R2DBC pour stocker et récupérer des données à partir d’Azure SQL Database.

Nettoyer les ressources

Pour propre toutes les ressources utilisées pendant ce guide de démarrage rapide, supprimez le groupe de ressources à l’aide de la commande suivante :

az group delete \
    --name $AZ_RESOURCE_GROUP \
    --yes

Étapes suivantes

Pour en savoir plus sur le déploiement d’une application Spring Data sur Azure Spring Apps et l’utilisation d’une identité managée, consultez Tutoriel : Déployer une application Spring sur Azure Spring Apps avec une connexion sans mot de passe à une base de données Azure.

Pour en savoir plus sur Spring et Azure, poursuivez vers le centre de documentation Spring sur Azure.

Voir aussi

Pour plus d’informations sur Spring Data R2DBC, consultez la documentation de référence de Spring.

Pour plus d’informations sur l’utilisation d’Azure avec Java, consultez Azure pour les développeurs Java et Utilisation d’Azure DevOps et Java.