← Назад к вопросам

Что такое синхронное API?

1.8 Middle🔥 191 комментариев
#SOLID и паттерны проектирования#Spring Boot и Spring Data

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Синхронное API

Синхронное API — это механизм взаимодействия между приложениями, где клиент отправляет запрос и блокируется в ожидании ответа от сервера. Клиент не может продолжать работу до получения результата. Это противоположность асинхронному API, где клиент отправляет запрос и может продолжать работу, получив результат позже через callback или pull механизм.

Основные концепции

Характеристики синхронного API:

  • Блокирующее выполнение — клиент ждёт ответ
  • Последовательность — запрос и ответ идут подряд
  • Простота — легко понять и реализовать
  • Предсказуемость — ясная последовательность выполнения
  • Задержки — медленнее асинхронных подходов
  • Синхронность — гарантия получения результата в одном месте

Простой пример синхронного REST API

import javax.ws.rs.*;
import javax.ws.rs.core.Response;

@Path("/api/users")
public class UserAPI {
    
    @GET
    @Path("/{id}")
    @Produces("application/json")
    public Response getUser(@PathParam("id") String userId) {
        // Синхронно получаем пользователя из БД
        User user = getUserFromDatabase(userId);
        
        if (user == null) {
            return Response.status(404).build();
        }
        
        // Возвращаем результат немедленно
        return Response.ok(user).build();
    }
    
    @POST
    @Consumes("application/json")
    @Produces("application/json")
    public Response createUser(User user) {
        // Синхронно сохраняем пользователя
        User savedUser = saveUserToDatabase(user);
        
        // Возвращаем сохранённого пользователя
        return Response.status(201).entity(savedUser).build();
    }
    
    private User getUserFromDatabase(String userId) {
        // Имитация блокирующего запроса к БД
        try {
            Thread.sleep(100); // Модель задержки
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return new User(userId, "John Doe");
    }
    
    private User saveUserToDatabase(User user) {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return user;
    }
}

class User {
    public String id;
    public String name;
    
    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

Клиент синхронного API

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;

public class SynchronousAPIClient {
    public static void main(String[] args) throws Exception {
        // Создание HTTP клиента
        HttpClient client = HttpClient.newHttpClient();
        
        // Синхронный GET запрос
        HttpRequest getRequest = HttpRequest.newBuilder()
            .uri(new URI("http://localhost:8080/api/users/123"))
            .GET()
            .build();
        
        System.out.println("Отправляем GET запрос...");
        // БЛОКИРУЕТ ВЫПОЛНЕНИЕ до получения ответа
        HttpResponse<String> getResponse = 
            client.send(getRequest, HttpResponse.BodyHandlers.ofString());
        
        System.out.println("Получен ответ: " + getResponse.body());
        System.out.println("Код статуса: " + getResponse.statusCode());
        
        // Синхронный POST запрос
        String jsonBody = "{\"name\":\"Jane Doe\"}"; 
        
        HttpRequest postRequest = HttpRequest.newBuilder()
            .uri(new URI("http://localhost:8080/api/users"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
            .build();
        
        System.out.println("\nОтправляем POST запрос...");
        // БЛОКИРУЕТ ВЫПОЛНЕНИЕ до получения ответа
        HttpResponse<String> postResponse = 
            client.send(postRequest, HttpResponse.BodyHandlers.ofString());
        
        System.out.println("Получен ответ: " + postResponse.body());
    }
}

Синхронный API с обработкой ошибок

import java.io.IOException;

public class RobustSynchronousAPI {
    
    public static class APIException extends Exception {
        public int statusCode;
        
        public APIException(String message, int statusCode) {
            super(message);
            this.statusCode = statusCode;
        }
    }
    
    public User fetchUser(String userId) throws APIException {
        try {
            HttpClient client = HttpClient.newHttpClient();
            
            HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("http://localhost:8080/api/users/" + userId))
                .GET()
                .timeout(java.time.Duration.ofSeconds(5))
                .build();
            
            // Синхронный вызов - ждём ответ
            HttpResponse<String> response = 
                client.send(request, HttpResponse.BodyHandlers.ofString());
            
            // Проверка статуса
            if (response.statusCode() == 200) {
                return parseUser(response.body());
            } else if (response.statusCode() == 404) {
                throw new APIException("Пользователь не найден", 404);
            } else {
                throw new APIException("Ошибка сервера", response.statusCode());
            }
            
        } catch (IOException e) {
            throw new APIException("Сетевая ошибка: " + e.getMessage(), -1);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new APIException("Запрос прерван", -1);
        } catch (Exception e) {
            throw new APIException("Неизвестная ошибка: " + e.getMessage(), -1);
        }
    }
    
    private User parseUser(String json) {
        // Парсинг JSON и создание объекта
        return new User("123", "John Doe");
    }
    
    public static void main(String[] args) {
        RobustSynchronousAPI api = new RobustSynchronousAPI();
        
        try {
            // Блокирует выполнение до получения результата
            User user = api.fetchUser("123");
            System.out.println("Пользователь: " + user.name);
        } catch (APIException e) {
            System.err.println("Ошибка API (" + e.statusCode + "): " + e.getMessage());
        }
    }
}

Синхронный API с Spring Boot

import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {
    
    private final OrderService orderService;
    
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }
    
    @GetMapping("/{orderId}")
    public ResponseEntity<Order> getOrder(@PathVariable String orderId) {
        // Синхронный вызов - блокирует поток до получения результата
        try {
            Order order = orderService.getOrderById(orderId);
            return ResponseEntity.ok(order);
        } catch (OrderNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }
    
    @PostMapping
    public ResponseEntity<Order> createOrder(@RequestBody CreateOrderRequest request) {
        // Синхронная обработка запроса
        Order createdOrder = orderService.createOrder(request);
        return ResponseEntity.status(201).body(createdOrder);
    }
}

@Service
public class OrderService {
    
    private final OrderRepository orderRepository;
    private final PaymentService paymentService;
    
    public OrderService(OrderRepository orderRepository, 
                       PaymentService paymentService) {
        this.orderRepository = orderRepository;
        this.paymentService = paymentService;
    }
    
    public Order getOrderById(String orderId) throws OrderNotFoundException {
        // Синхронный запрос к БД
        return orderRepository.findById(orderId)
            .orElseThrow(() -> new OrderNotFoundException("Заказ не найден"));
    }
    
    public Order createOrder(CreateOrderRequest request) {
        // Синхронные операции в последовательности
        
        // 1. Проверка инвентаря (синхронно блокирует)
        if (!inventoryService.isAvailable(request.getProductId())) {
            throw new OutOfStockException("Товар отсутствует");
        }
        
        // 2. Обработка платежа (синхронно блокирует)
        PaymentResult paymentResult = 
            paymentService.processPayment(request.getAmount());
        
        if (!paymentResult.isSuccessful()) {
            throw new PaymentException("Платёж не прошёл");
        }
        
        // 3. Создание заказа (синхронно блокирует)
        Order order = new Order(request);
        return orderRepository.save(order);
    }
}

Преимущества синхронного API

  • Простота — легко понять и отлаживать
  • Предсказуемость — ясная последовательность выполнения
  • Согласованность — гарантия получения результата
  • Меньше сложности — нет callback hell или Future chains
  • Синхронизация данных — результат доступен сразу

Недостатки синхронного API

  • Блокирование — потоки ждут ответа
  • Масштабируемость — требует больше потоков для одновременных запросов
  • Задержки — медленнее асинхронных подходов
  • Потребление ресурсов — высокое использование памяти и CPU
  • Зависимость от скорости — медленный сервер замораживает клиента

Когда использовать синхронное API

  • Простые CRUD операции
  • Операции, которые зависят от результатов друг друга
  • Приложения с низкой нагрузкой
  • Внутренние микросервисы с надёжной сетью
  • Когда простота важнее производительности

Синхронное API — фундаментальный подход в веб-разработке, хотя для высоконагруженных систем часто используют асинхронные альтернативы.