← Назад к вопросам
С помощью чего делали интеграции в команде
2.3 Middle🔥 131 комментариев
#REST API и микросервисы#Брокеры сообщений
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Интеграции с внешними системами в команде
Стек технологий для интеграций
В разных проектах мы использовали разные подходы. Расскажу о самых эффективных.
1. REST API + Spring RestTemplate / WebClient
Проект: Платёжная система (интеграция с 5+ платёжными шлюзами)
// Старый подход (Spring 4.x)
@Service
public class StripePaymentService {
@Autowired
private RestTemplate restTemplate;
public PaymentResponse processPayment(PaymentRequest request) {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("sk_test_xxx", "");
HttpEntity<StripeRequest> entity = new HttpEntity<>(mapRequest(request), headers);
ResponseEntity<StripeResponse> response = restTemplate.postForEntity(
"https://api.stripe.com/v1/charges",
entity,
StripeResponse.class
);
return mapResponse(response.getBody());
}
}
// Новый подход (Spring 5+, асинхронный)
@Service
public class StripePaymentServiceAsync {
@Autowired
private WebClient webClient;
public Mono<PaymentResponse> processPayment(PaymentRequest request) {
return webClient
.post()
.uri("https://api.stripe.com/v1/charges")
.header("Authorization", "Bearer sk_test_xxx")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(mapRequest(request))
.retrieve()
.bodyToMono(StripeResponse.class)
.map(this::mapResponse);
}
}
2. Message Brokers: RabbitMQ / Kafka
Проект: Система уведомлений (Email, SMS, Push)
// RabbitMQ
@Configuration
public class RabbitConfig {
public static final String NOTIFICATION_QUEUE = "notification.queue";
public static final String NOTIFICATION_EXCHANGE = "notification.exchange";
@Bean
public Queue notificationQueue() {
return new Queue(NOTIFICATION_QUEUE, true);
}
@Bean
public Exchange notificationExchange() {
return new DirectExchange(NOTIFICATION_EXCHANGE, true, false);
}
@Bean
public Binding binding(Queue queue, Exchange exchange) {
return BindingBuilder
.bind(queue)
.to(exchange)
.with("notification.*");
}
}
@Service
public class NotificationPublisher {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendNotification(Notification notification) {
rabbitTemplate.convertAndSend(
NOTIFICATION_EXCHANGE,
"notification.email",
notification
);
}
}
@Component
public class NotificationConsumer {
@RabbitListener(queues = RabbitConfig.NOTIFICATION_QUEUE)
public void handleNotification(Notification notification) {
// Отправляем Email/SMS
mailService.send(notification);
}
}
// Kafka (более мощный)
@Service
public class KafkaNotificationPublisher {
@Autowired
private KafkaTemplate<String, Notification> kafkaTemplate;
public void sendNotification(Notification notification) {
kafkaTemplate.send("notifications", notification.getId(), notification);
}
}
@Component
public class KafkaNotificationConsumer {
@KafkaListener(topics = "notifications", groupId = "notification-group")
public void listen(Notification notification) {
mailService.send(notification);
}
}
3. SOAP (для legacy систем)
Проект: Интеграция с банковской системой (1С)
@Configuration
public class SoapConfig {
@Bean
public WebServiceTemplate webServiceTemplate() {
return new WebServiceTemplate(new HttpComponentsMessageSender());
}
}
@Service
public class BankIntegrationService {
@Autowired
private WebServiceTemplate webServiceTemplate;
private static final String URL = "https://bank.example.com/soap";
public BankAccountResponse getAccountInfo(String accountId) {
GetAccountRequest request = new GetAccountRequest();
request.setAccountId(accountId);
request.setToken("bank_token_xxx");
BankAccountResponse response = (BankAccountResponse) webServiceTemplate
.marshalSendAndReceive(URL, request);
return response;
}
}
4. Scheduled Tasks / Polling
Проект: Синхронизация данных с внешним хранилищем
@Component
public class DataSyncScheduler {
@Autowired
private ExternalDataService externalService;
@Autowired
private LocalDataRepository localRepository;
// Каждые 5 минут
@Scheduled(fixedRate = 300000)
public void syncData() {
List<ExternalData> external = externalService.fetchAll();
external.forEach(item -> {
LocalData local = localRepository.findById(item.getId()).orElse(new LocalData());
local.update(item);
localRepository.save(local);
});
logger.info("Data sync completed: {} items", external.size());
}
}
5. Webhooks (для real-time интеграций)
Проект: Платёжная система слушает события от Stripe
// У нас (эндпоинт для входящих webhook'ов)
@RestController
@RequestMapping("/webhooks")
public class StripeWebhookController {
@Autowired
private PaymentWebhookService webhookService;
@PostMapping("/stripe")
public ResponseEntity<Void> handleStripeEvent(@RequestBody String payload,
@RequestHeader("Stripe-Signature") String signature) {
// Проверяем подпись
if (!verifySignature(payload, signature)) {
return ResponseEntity.badRequest().build();
}
Event event = Gson.fromJson(payload, Event.class);
webhookService.processEvent(event);
return ResponseEntity.ok().build();
}
private boolean verifySignature(String payload, String signature) {
String secret = "whsec_xxx";
// HMAC-SHA256 verification
return true;
}
}
// Обработка событий
@Service
public class PaymentWebhookService {
@Transactional
public void processEvent(Event event) {
switch (event.getType()) {
case "charge.succeeded":
handleChargeSucceeded((ChargeData) event.getData());
break;
case "charge.failed":
handleChargeFailed((ChargeData) event.getData());
break;
}
}
private void handleChargeSucceeded(ChargeData data) {
Payment payment = paymentRepository.findById(data.getMetadata("order_id")).orElseThrow();
payment.setStatus(PaymentStatus.COMPLETED);
paymentRepository.save(payment);
// Отправляем email клиенту
}
}
6. GraphQL
Проект: API для мобильного приложения
@Component
public class OrderQueryResolver implements GraphQLQueryResolver {
@Autowired
private OrderService orderService;
public Order order(String id) {
return orderService.findById(id);
}
public List<Order> orders(int limit, int offset) {
return orderService.findAll(limit, offset);
}
}
@Component
public class OrderMutationResolver implements GraphQLMutationResolver {
@Autowired
private OrderService orderService;
public Order createOrder(CreateOrderInput input) {
return orderService.create(input);
}
}
7. WebSockets (для real-time)
Проект: Live чат / мониторинг
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic", "/queue");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
}
@Controller
public class ChatController {
@MessageMapping("/chat.sendMessage")
@SendTo("/topic/public")
public ChatMessage sendMessage(@Payload ChatMessage message) {
return message;
}
}
Best Practices интеграций в команде
1. Retry логика
@Service
public class ResilientPaymentService {
@Retryable(value = {IOException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))
public PaymentResponse process(PaymentRequest request) throws IOException {
return restClient.post(request);
}
}
2. Circuit Breaker
@Service
@CircuitBreaker(name = "paymentService", fallbackMethod = "fallback")
public Mono<PaymentResponse> processPayment(PaymentRequest request) {
return externalPaymentAPI.process(request);
}
public Mono<PaymentResponse> fallback(PaymentRequest request, Exception ex) {
// Вернуть дефолтный ответ или сохранить в очередь
return Mono.just(PaymentResponse.PENDING);
}
3. Логирование и мониторинг
@Aspect
@Component
public class IntegrationLogging {
@Around("@annotation(IntegrationPoint)")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
long duration = System.currentTimeMillis() - start;
logger.info("Integration [{}] completed in {}ms",
pjp.getSignature().getName(), duration);
return result;
}
}
Мой выбор в новых проектах
- Синхронные REST API → WebClient
- Асинхронные события → Kafka
- Real-time → WebSockets
- Legacy → SOAP (но стараемся мигрировать)
- Надёжность → Circuit Breaker + Retry