🚀 Getting Started: Seu Primeiro Serviço com o SDK
Acesso Antecipado (Beta)Esta documentação refere-se a uma versão em acesso antecipado do SDK Sankhya. As funcionalidades e APIs estão sujeitas a modificações. Para obter acesso, envie um e-mail para [email protected] informando a
appkeydo seu projeto.
🚀 Getting Started: Seu Primeiro Serviço com o SDK
Este guia prático demonstra como construir um serviço "Hello, World!" utilizando os principais recursos do SDK Sankhya: injeção de dependências, controle transacional, e a definição de entidades e repositórios.
🛠️ Pré-requisitos
Garanta que seu projeto esteja configurado para usar a versão 2.0.0 ou superior do plugin do Add-on Studio. Verifique seu arquivo build.gradle:
// build.gradle
buildscript {
// ...
dependencies {
classpath "br.com.sankhya.studio:gradle-plugin:2.0.+" // Garanta a versão 2.0.0 ou superior
// ... outras dependências
}
}🧩 Componentes Principais
Vamos construir um serviço para gerenciar uma entidade Veiculo.
1. A Entidade (Veiculo.java)
Veiculo.java)As entidades agora são POJOs (Plain Old Java Objects) anotados, de forma muito similar ao padrão JPA. Isso substitui o DynamicVO por classes Java modernas e fortemente tipadas.
Importante: Lembre-se que a entidade (TGFVEIneste caso) ainda precisa ser definida no Dicionário de Dados para que a plataforma a reconheça.
// src/main/java/br/com/meuaddon/model/Veiculo.java
package br.com.meuaddon.model;
import br.com.sankhya.studio.persistence.Column;
import br.com.sankhya.studio.persistence.JapeEntity;
import br.com.sankhya.studio.persistence.Id;
import lombok.Data;
@Data
@JapeEntity(entity="Veiculo", table="TGFVEI")
public class Veiculo {
@Id
@Column(name = "CODVEICULO")
private Long id;
@Column(name = "PLACA")
private String placa;
@Column(name = "ATIVO")
private boolean ativo; // Use tipos primitivos sempre que possível
}Tipos de Dados Suportados:
O SDK suporta uma vasta gama de tipos modernos, incluindo:
- Primitivos:
long,int,boolean,float,double - Wrappers:
Long,Integer,Boolean, etc. - Números de alta precisão:
BigDecimal,BigInteger - Texto:
String - Datas e Horas:
Timestamp,LocalDate,LocalDateTime - Enums
2. O Repositório (VeiculoRepository.java)
VeiculoRepository.java)O repositório é a camada de acesso a dados. Crie uma interface que estenda JapeRepository, e o SDK cuidará da implementação dos métodos de CRUD (save, findById, delete, etc.) e de busca que você definir.
// src/main/java/br/com/meuaddon/repository/VeiculoRepository.java
package br.com.meuaddon.repository;
import br.com.sankhya.sdk.data.repository.Criteria;
import br.com.sankhya.sdk.data.repository.Delete;
import br.com.sankhya.sdk.data.repository.JapeRepository;
import br.com.sankhya.studio.stereotypes.Repository;
import br.com.meuaddon.model.Veiculo;
import java.util.List;
import java.util.Optional;
@Repository
public interface VeiculoRepository extends JapeRepository<Long, Veiculo> {
/**
* O SDK implementa automaticamente buscas por campos da entidade.
* Retorna um Optional, pois o veículo pode não existir.
*/
Optional<Veiculo> findByPlaca(String placa);
/**
* Use @Criteria para consultas mais complexas com JAPE criteria.
* O SDK mapeia os parâmetros do método para a criteria.
*/
@Criteria("this.ATIVO = 'S' AND this.PLACA LIKE :placa")
List<Veiculo> findAtivosPorPlaca(String placa);
/**
* Use @Delete para criar um método de exclusão customizado.
*/
@Delete("this.PLACA = :placa")
void deleteByPlaca(String placa);
}- Retornos Flexíveis: Métodos podem retornar
Optional<T>, um únicoPOJOou umaList<T>.
3. O DTO (VeiculoDTO.java)
VeiculoDTO.java)DTOs (Data Transfer Objects) são usados para transportar dados entre as camadas (ex: da requisição do serviço para a lógica de negócio). O SDK integra o Bean Validation para validações automáticas.
// src/main/java/br/com/meuaddon/dto/VeiculoDTO.java
package br.com.meuaddon.dto;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import lombok.Data;
@Data
public class VeiculoDTO {
@NotBlank(message = "A placa não pode ser vazia.")
@Size(min = 7, max = 8, message = "A placa deve ter entre 7 e 8 caracteres.")
private String placa;
private boolean ativo;
}4. O Serviço (VeiculoService.java)
VeiculoService.java)Esta é a camada que contém a lógica de negócio. Ela usa injeção de dependências para obter o repositório e @Transactional para garantir a consistência dos dados.
// src/main/java/br/com/meuaddon/service/VeiculoService.java
package br.com.meuaddon.service;
import br.com.meuaddon.dto.VeiculoDTO;
import br.com.meuaddon.model.Veiculo;
import br.com.meuaddon.repository.VeiculoRepository;
import br.com.sankhya.studio.stereotypes.Service;
import br.com.sankhya.studio.transaction.Transactional;
import javax.inject.Inject;
import javax.validation.Valid;
@Service // A anotação @Service expõe esta classe como um serviço.
public class VeiculoService {
private final VeiculoRepository repository;
@Inject // O SDK injeta a dependência do repositório via construtor.
public VeiculoService(VeiculoRepository repository) {
this.repository = repository;
}
/**
* Cria um novo veículo.
* A anotação @Transactional garante que a operação seja atômica.
* A anotação @Valid dispara a validação do DTO.
*/
@Transactional
public Long cadastrarNovoVeiculo(@Valid VeiculoDTO dto) {
if (repository.findByPlaca(dto.getPlaca()).isPresent()) {
throw new IllegalStateException("Veículo com esta placa já existe.");
}
Veiculo novoVeiculo = new Veiculo();
novoVeiculo.setPlaca(dto.getPlaca());
novoVeiculo.setAtivo(dto.isAtivo());
repository.save(novoVeiculo);
return novoVeiculo.getId();
}
/**
* Atualiza os dados de um veículo existente.
*/
@Transactional
public void atualizarVeiculo(Long id, @Valid VeiculoDTO dto) {
Veiculo veiculo = repository.findById(id)
.orElseThrow(() -> new IllegalStateException("Veículo não encontrado com o ID: " + id));
veiculo.setPlaca(dto.getPlaca());
veiculo.setAtivo(dto.isAtivo());
repository.save(veiculo); // O método save() também atualiza a entidade.
}
/**
* Exclui um veículo pela placa.
*/
@Transactional
public void excluirVeiculo(String placa) {
repository.deleteByPlaca(placa);
}
}Resumo do Fluxo
- Requisição: Um cliente chama o serviço
VeiculoService(ex: métodocadastrarNovoVeiculo) com um JSON contendo os dados doVeiculoDTO. - Controller (SDK Interno): O SDK recebe a requisição, desserializa o JSON para
VeiculoDTOe chama o método correspondente noVeiculoService. - Validação: A anotação
@Validaciona as validações definidas noVeiculoDTO. Se a placa for inválida, uma exceção é lançada e a execução para. - Transação: A anotação
@Transactionalinicia uma transação no banco de dados. - Lógica de Negócio: O serviço executa a lógica, como verificar se a placa já existe.
- Persistência: O serviço utiliza o
VeiculoRepositorypara salvar, atualizar ou excluir a entidadeVeiculo. - Commit/Rollback: Se tudo ocorrer bem, a transação é commitada. Se qualquer exceção for lançada, a transação é revertida (rollback).
- Resposta: O resultado (como o ID do novo veículo) é retornado ao cliente.
Benefícios e Princípios de Desenvolvimento
Adotar esta arquitetura moderniza o desenvolvimento e traz benefícios significativos de organização, manutenibilidade e testabilidade, alinhando o código a princípios consolidados como Clean Code e SOLID.
Injeção de Dependências (ID)
- O que é? Em vez de uma classe criar suas próprias dependências (ex:
new VeiculoRepository()), elas são "injetadas" de fora (pelo construtor, por exemplo). - Legibilidade e Clean Code: O construtor de uma classe declara explicitamente tudo o que ela precisa para funcionar. Isso torna as dependências claras e o código mais fácil de entender.
- Princípio da Inversão de Dependência (SOLID): A
VeiculoServicenão depende da implementação concreta doVeiculoRepository, mas sim de sua interface (abstração). Isso desacopla o código, permitindo que a implementação do repositório seja trocada sem impactar a lógica de negócio. - Testabilidade: Facilita a criação de testes unitários. É possível "mockar" (simular) o
VeiculoRepositorypara testar aVeiculoServicede forma isolada, sem a necessidade de uma conexão real com o banco de dados.
Definição de Repositórios
- O que é? O Padrão de Repositório abstrai a camada de acesso a dados, tratando a fonte de dados como uma coleção de objetos.
- Legibilidade e Clean Code: Centraliza toda a lógica de acesso a dados em um único lugar (a interface do repositório). A camada de serviço (
VeiculoService) apenas utiliza métodos comofindByPlaca, sem precisar se preocupar com a construção de queries SQL ou com a forma como os dados são persistidos. - Princípio da Responsabilidade Única (SOLID): O repositório tem uma única responsabilidade: gerenciar a persistência da entidade
Veiculo. A classe de serviço tem outra: orquestrar a lógica de negócio. Essa separação de preocupações é a base de uma arquitetura limpa e organizada, tornando o código mais fácil de manter e escalar.
Updated 4 days ago
