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

Какой HTTP запрос будешь использовать для API, который по номеру карточки возвращает клиента?

1.2 Junior🔥 111 комментариев
#REST API и микросервисы

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

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

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

# Выбор HTTP метода для поиска клиента по номеру карточки

Правильный выбор: GET

Для получения информации о клиенте по номеру карточки следует использовать GET запрос.

Обоснование

HTTP методы имеют следующие семантики:

  • GET: Получение данных (безопасен, идемпотентен, нет побочных эффектов)
  • POST: Создание новых ресурсов
  • PUT: Полное обновление ресурса
  • PATCH: Частичное обновление ресурса
  • DELETE: Удаление ресурса

Поскольку мы только получаем информацию о клиенте и не создаём, не обновляем и не удаляем данные, GET является правильным выбором.

Варианты реализации

Вариант 1: Номер карточки как параметр пути (RESTful подход)

// Клиент
GET /api/v1/customers?card_number=1234567890123456

// Сервер (Spring Boot)
@GetMapping("/api/v1/customers")
public ResponseEntity<Customer> getCustomerByCardNumber(
    @RequestParam("card_number") String cardNumber) {
    Customer customer = customerService.findByCardNumber(cardNumber);
    if (customer == null) {
        return ResponseEntity.notFound().build();
    }
    return ResponseEntity.ok(customer);
}

Вариант 2: Номер карточки в пути (более чистый REST)

GET /api/v1/cards/1234567890123456/customer

// Сервер
@GetMapping("/api/v1/cards/{cardNumber}/customer")
public ResponseEntity<Customer> getCustomerByCard(
    @PathVariable("cardNumber") String cardNumber) {
    Customer customer = customerService.findByCardNumber(cardNumber);
    return ResponseEntity.ok(customer);
}

Вариант 3: Поиск через отдельный endpoint

GET /api/v1/customers/search?card=1234567890123456

// Сервер
@GetMapping("/api/v1/customers/search")
public ResponseEntity<Customer> searchCustomer(
    @RequestParam("card") String cardNumber) {
    Customer customer = customerService.findByCardNumber(cardNumber);
    return ResponseEntity.ok(customer);
}

Пример клиентского кода

Использование HttpClient (Java 11+):

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

public class CustomerClient {
    private static final HttpClient httpClient = HttpClient.newHttpClient();
    private static final String API_BASE = "https://api.example.com/api/v1";
    
    public Customer getCustomerByCardNumber(String cardNumber) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(API_BASE + "/customers?card_number=" + cardNumber))
            .GET()
            .header("Accept", "application/json")
            .build();
        
        HttpResponse<String> response = httpClient.send(
            request,
            HttpResponse.BodyHandlers.ofString()
        );
        
        if (response.statusCode() == 200) {
            return parseJson(response.body());
        } else if (response.statusCode() == 404) {
            return null;
        } else {
            throw new RuntimeException("API Error: " + response.statusCode());
        }
    }
    
    private Customer parseJson(String json) {
        // Парсинг JSON (используй Gson, Jackson, или другую библиотеку)
        return new ObjectMapper().readValue(json, Customer.class);
    }
}

Использование RestTemplate (Spring):

@Component
public class CustomerClient {
    @Autowired
    private RestTemplate restTemplate;
    
    private static final String API_URL = "https://api.example.com/api/v1/customers";
    
    public Customer getCustomerByCardNumber(String cardNumber) {
        try {
            String url = API_URL + "?card_number=" + cardNumber;
            Customer customer = restTemplate.getForObject(url, Customer.class);
            return customer;
        } catch (HttpClientErrorException.NotFound e) {
            return null;
        }
    }
}

Использование WebClient (Spring WebFlux, асинхронный):

@Component
public class CustomerWebClient {
    private final WebClient webClient;
    
    public Mono<Customer> getCustomerByCardNumber(String cardNumber) {
        return webClient.get()
            .uri("/api/v1/customers?card_number={cardNumber}", cardNumber)
            .retrieve()
            .bodyToMono(Customer.class)
            .onErrorResume(WebClientResponseException.NotFound.class, e -> Mono.empty());
    }
}

Коды ответов

  • 200 OK: Клиент найден, возвращаются данные
  • 404 Not Found: Клиент с такой карточкой не найден
  • 400 Bad Request: Некорректный формат номера карточки
  • 401 Unauthorized: Требуется аутентификация
  • 403 Forbidden: Нет доступа к данным
  • 500 Internal Server Error: Ошибка сервера

Безопасность

  • Валидация: Проверить формат номера карточки (обычно 16 цифр)
  • Шифрование: Использовать HTTPS (не HTTP)
  • Маскирование: В логах показывать только последние 4 цифры (****1234)
  • Rate limiting: Ограничить количество запросов для предотвращения перебора

Итог

Для получения клиента по номеру карточки используй GET запрос. Это соответствует REST архитектурным принципам, так как операция не модифицирует данные на сервере.