Usar o Spring Data R2DBC com o Banco de Dados do Azure para PostgreSQL
Este artigo demonstra a criação de um aplicativo de exemplo que usa o Spring Data R2DBC para armazenar e recuperar informações em um banco de dados do Azure Database for PostgreSQL . O exemplo usará a implementação R2DBC para PostgreSQL do repositório r2dbc-postgresql no GitHub.
O R2DBC permite utilizar APIs reativas nas bases de dados relacionais tradicionais. Você pode usá-lo com o Spring WebFlux para criar aplicativos Spring Boot totalmente reativos que usam APIs sem bloqueio. Ele fornece melhor escalabilidade do que a abordagem clássica de "um thread por conexão".
Pré-requisitos
Uma assinatura do Azure - crie uma gratuitamente.
Java Development Kit (JDK), versão 8 ou superior.
cURL ou um utilitário HTTP semelhante para testar a funcionalidade.
Veja o aplicativo de exemplo
Neste artigo, você codificará um aplicativo de exemplo. Se você quiser ir mais rápido, este aplicativo já está codificado e disponível em https://github.com/Azure-Samples/quickstart-spring-data-r2dbc-postgresql.
Preparar o ambiente de trabalho
Primeiro, configure algumas variáveis de ambiente executando os seguintes comandos:
export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_POSTGRESQL_ADMIN_USERNAME=spring
export AZ_POSTGRESQL_ADMIN_PASSWORD=<YOUR_POSTGRESQL_ADMIN_PASSWORD>
export AZ_POSTGRESQL_NON_ADMIN_USERNAME=nonspring
export AZ_POSTGRESQL_NON_ADMIN_PASSWORD=<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
Substitua os marcadores de posição pelos seguintes valores, que são utilizados ao longo deste artigo:
<YOUR_DATABASE_SERVER_NAME>
: O nome do seu servidor PostgreSQL, que deve ser exclusivo no Azure.<YOUR_DATABASE_NAME>
: O nome do banco de dados do servidor PostgreSQL, que deve ser exclusivo no Azure.<YOUR_AZURE_REGION>
: A região do Azure que você usará. Pode utilizar a regiãoeastus
por predefinição, mas recomendamos que configure uma região mais próxima do local onde vive. Você pode ver a lista completa de regiões disponíveis usandoaz account list-locations
.<YOUR_POSTGRESQL_ADMIN_PASSWORD>
e<YOUR_POSTGRESQL_NON_ADMIN_PASSWORD>
: A senha do seu servidor de banco de dados PostgreSQL, que deve ter um mínimo de oito caracteres. Os caracteres devem ser de três das seguintes categorias: letras maiúsculas inglesas, letras minúsculas inglesas, números (0-9) e caracteres não alfanuméricos (!, $, #, % e assim por diante).<YOUR_LOCAL_IP_ADDRESS>
: O endereço IP do seu computador local, a partir do qual irá executar a sua aplicação Spring Boot. Uma maneira conveniente de encontrá-lo é abri-whatismyip.akamai.com.
Nota
A Microsoft recomenda o uso do fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste procedimento, como para bancos de dados, caches, mensagens ou serviços de IA, requer um grau muito alto de confiança no aplicativo e traz riscos não presentes em outros fluxos. Use esse fluxo somente quando opções mais seguras, como identidades gerenciadas para conexões sem senha ou sem chave, não forem viáveis. Para operações de máquina local, prefira identidades de usuário para conexões sem senha ou sem chave.
Em seguida, crie um grupo de recursos usando o seguinte comando:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
--output tsv
Criar uma instância do Banco de Dados do Azure para PostgreSQL e configurar o usuário administrador
A primeira coisa que você criará é um servidor PostgreSQL gerenciado com um usuário administrador.
Nota
Você pode ler informações mais detalhadas sobre como criar servidores PostgreSQL em Criar um Banco de Dados do Azure para o servidor PostgreSQL usando o portal do Azure.
az postgres flexible-server create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--location $AZ_LOCATION \
--admin-user $AZ_POSTGRESQL_ADMIN_USERNAME \
--admin-password $AZ_POSTGRESQL_ADMIN_PASSWORD \
--yes \
--output tsv
Configurar um banco de dados PostgreSQL
O servidor PostgreSQL que você criou anteriormente está vazio. Use o comando a seguir para criar um novo banco de dados.
az postgres flexible-server db create \
--resource-group $AZ_RESOURCE_GROUP \
--database-name $AZ_DATABASE_NAME \
--server-name $AZ_DATABASE_SERVER_NAME \
--output tsv
Configurar uma regra de firewall para o seu servidor PostgreSQL
As instâncias do Banco de Dados do Azure para PostgreSQL são protegidas por padrão. O serviço tem uma firewall que não permite ligações de entrada. Para poder usar seu banco de dados, você precisa adicionar uma regra de firewall que permitirá que o endereço IP local acesse o servidor de banco de dados.
Como você configurou seu endereço IP local no início deste artigo, você pode abrir o firewall do servidor executando o seguinte comando:
az postgres flexible-server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS \
--output tsv
Se você estiver se conectando ao seu servidor PostgreSQL a partir do Subsistema Windows para Linux (WSL) em um computador Windows, precisará adicionar o ID do host WSL ao firewall.
Obtenha o endereço IP da sua máquina host executando o seguinte comando no WSL:
cat /etc/resolv.conf
Copie o endereço IP após o termo nameserver
e, em seguida, use o seguinte comando para definir uma variável de ambiente para o endereço IP WSL:
export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>
Em seguida, use o seguinte comando para abrir o firewall do servidor para seu aplicativo baseado em WSL:
az postgres flexible-server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME \
--rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
--start-ip-address $AZ_WSL_IP_ADDRESS \
--end-ip-address $AZ_WSL_IP_ADDRESS \
--output tsv
Criar um usuário não administrador do PostgreSQL e conceder permissão
Em seguida, crie um usuário não administrador e conceda todas as permissões ao banco de dados.
Nota
Você pode ler informações mais detalhadas sobre como criar usuários do PostgreSQL em Criar usuários no Banco de Dados do Azure para PostgreSQL.
Crie um script SQL chamado create_user.sql para criar um usuário não administrador. Adicione o seguinte conteúdo e salve-o localmente:
Nota
A Microsoft recomenda o uso do fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste procedimento, como para bancos de dados, caches, mensagens ou serviços de IA, requer um grau muito alto de confiança no aplicativo e traz riscos não presentes em outros fluxos. Use esse fluxo somente quando opções mais seguras, como identidades gerenciadas para conexões sem senha ou sem chave, não forem viáveis. Para operações de máquina local, prefira identidades de usuário para conexões sem senha ou sem chave.
cat << EOF > create_user.sql
CREATE ROLE "$AZ_POSTGRESQL_NON_ADMIN_USERNAME" WITH LOGIN PASSWORD '$AZ_POSTGRESQL_NON_ADMIN_PASSWORD';
GRANT ALL PRIVILEGES ON DATABASE $AZ_DATABASE_NAME TO "$AZ_POSTGRESQL_NON_ADMIN_USERNAME";
EOF
Em seguida, use o seguinte comando para executar o script SQL para criar o usuário não administrador do Microsoft Entra:
psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$AZ_POSTGRESQL_ADMIN_USERNAME dbname=$AZ_DATABASE_NAME port=5432 password=$AZ_POSTGRESQL_ADMIN_PASSWORD sslmode=require" < create_user.sql
Agora use o seguinte comando para remover o arquivo de script SQL temporário:
rm create_user.sql
Criar uma aplicação Spring Boot reativa
Para criar um aplicativo Spring Boot reativo, usaremos o Spring Initializr. A aplicação que iremos criar utiliza:
- Bota de mola 2.7.11.
- As seguintes dependências: Spring Reative Web (também conhecido como Spring WebFlux) e Spring Data R2DBC.
Gerar a aplicação com o Spring Initializr
Gere o aplicativo na linha de comando usando o seguinte comando:
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 -
Adicionar a implementação reativa do driver PostgreSQL
Abra o arquivo pom.xml do projeto gerado e adicione o driver PostgreSQL reativo do repositório r2dbc-postgresql no GitHub. Após a spring-boot-starter-webflux
dependência, adicione o seguinte texto:
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<version>0.8.12.RELEASE</version>
<scope>runtime</scope>
</dependency>
Configurar o Spring Boot para usar o Banco de Dados do Azure para PostgreSQL
Abra o arquivo src/main/resources/application.properties e adicione o seguinte texto:
logging.level.org.springframework.data.r2dbc=DEBUG
spring.r2dbc.url=r2dbc:pool:postgres://$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com:5432/$AZ_DATABASE_NAME
spring.r2dbc.username=nonspring
spring.r2dbc.password=$AZ_POSTGRESQL_NON_ADMIN_PASSWORD
spring.r2dbc.properties.sslMode=REQUIRE
Substitua as $AZ_DATABASE_SERVER_NAME
variáveis , $AZ_DATABASE_NAME
e e $AZ_POSTGRESQL_NON_ADMIN_PASSWORD
pelos valores que você configurou no início deste artigo.
Aviso
Por motivos de segurança, o Banco de Dados do Azure para PostgreSQL requer o uso de conexões SSL. É por isso que você precisa adicionar a spring.r2dbc.properties.sslMode=REQUIRE
propriedade de configuração, caso contrário, o driver R2DBC PostgreSQL tentará se conectar usando uma conexão insegura, que falhará.
Nota
Para um melhor desempenho, a propriedade é configurada spring.r2dbc.url
para usar um pool de conexões usando r2dbc-pool.
Agora você deve ser capaz de iniciar seu aplicativo usando o wrapper Maven fornecido da seguinte maneira:
./mvnw spring-boot:run
Eis uma captura de ecrã da aplicação em execução pela primeira vez:
Criar o esquema da base de dados
Dentro da classe principal DemoApplication
, configure um novo Spring bean que criará um esquema de banco de dados, usando o seguinte código:
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;
}
}
Este Spring bean usa um arquivo chamado schema.sql, portanto, crie esse arquivo na pasta src/main/resources e adicione o seguinte texto:
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
Pare o aplicativo em execução e inicie-o novamente usando o seguinte comando. Agora, a aplicação irá utilizar a base de dados demo
que criou anteriormente e criar uma tabela todo
na mesma.
./mvnw spring-boot:run
Aqui está uma captura de tela da tabela do banco de dados enquanto ela está sendo criada:
Codificar a aplicação
Em seguida, adicione o código Java que usará o R2DBC para armazenar e recuperar dados do seu servidor PostgreSQL.
Crie uma nova Todo
classe Java, ao lado da DemoApplication
classe, usando o seguinte código:
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;
}
}
Esta classe é um modelo de domínio mapeado na tabela todo
que criou anteriormente.
Para gerir essa classe, precisa de um repositório. Defina uma nova TodoRepository
interface no mesmo pacote, usando o seguinte código:
package com.example.demo;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
public interface TodoRepository extends ReactiveCrudRepository<Todo, Long> {
}
Este repositório é um repositório reativo que o Spring Data R2DBC gerencia.
Conclua o aplicativo criando um controlador que possa armazenar e recuperar dados. Implemente uma classe TodoController
no mesmo pacote e adicione o seguinte código:
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();
}
}
Por último, pare a aplicação e inicie-a novamente com o seguinte comando:
./mvnw spring-boot:run
Testar a aplicação
Pode utilizar o cURL para testar a aplicação.
Comece por criar um item "todo" na base de dados ao utilizar o seguinte comando:
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
Este comando deve retornar o item criado, conforme mostrado aqui:
{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}
Em seguida, recupere os dados usando uma nova solicitação cURL com o seguinte comando:
curl http://127.0.0.1:8080
Este comando retornará a lista de itens "todo", incluindo o item que você criou, conforme mostrado aqui:
[{"id":1,"description":"configuration","details":"congratulations, you have set up R2DBC correctly!","done":true}]
Aqui está uma captura de tela dessas solicitações de cURL:
Parabéns! Você criou um aplicativo Spring Boot totalmente reativo que usa o R2DBC para armazenar e recuperar dados do Banco de Dados do Azure para PostgreSQL.
Clean up resources (Limpar recursos)
Para limpar todos os recursos usados durante este início rápido, exclua o grupo de recursos usando o seguinte comando:
az group delete \
--name $AZ_RESOURCE_GROUP \
--yes
Próximos passos
Para saber mais sobre como implantar um aplicativo Spring Data no Azure Spring Apps e usar a identidade gerenciada, consulte Tutorial: Implantar um aplicativo Spring no Azure Spring Apps com uma conexão sem senha para um banco de dados do Azure.
Para saber mais sobre o Spring e o Azure, avance para o centro de documentação relativa ao Spring no Azure.
Consulte também
Para obter mais informações sobre o Spring Data R2DBC, consulte a documentação de referência do Spring.
Para obter mais informações sobre a utilização do Azure com o Java, veja Azure para programadores de Java e Trabalhar com o Azure DevOps e Java.