Skip to content

API Specification for Product

KalachyanD edited this page Jul 23, 2023 · 1 revision

API for front-end

1. Get the list of all products page by page, sorted by the passed attribute:

HTTP Method: GET

URL: /api/v1/products

Query Parameters:

Parameter Type Required Description Valid values Default
page integer false number of the page any integer >= 0 0
size integer false amount of products on the page any integer > 0 50
sort_attribute string false sorting attribute one of [price, quantity] price
sort_direction string false sorting direction one of [asc, desc] desc

Full query example: /api/v1/products?page=0&size=10&sort_attribute=price&sort_direction=desc

Return products (json):

{
  "products": [
    {
      "id": "3dc8d76a-d892-4875-8e97-ca4240929c4a",
      "name": "Arabica",
      "description": "A type of coffee that has a noble and mild taste with piquant sourness and exquisite aroma.
                      caffeine content does not exceed 1.5%.",
      "price": {
        "amount": 3.00,
        "currency": "USD"
      },
      "quantity": 10
    },
    {
      "id": "5f561767-c8d9-4cf2-ab10-e1b04c71ce52",
      "name": "Robusta",
      "description": "A kind of coffee for true connoisseurs of strength - grains contain a lot of caffeine. 
                      Robusta has a simpler, bitter and strong taste.",
      "price": {
        "amount": 2.00,
        "currency": "USD"
      },
      "quantity": 15
    }
  ],
  "page": 0,
  "size": 2,
  "totalElements": 30,
  "totalPages": 15
}
name           product name
description    product description
price          product price
    amount              price
    currency            currency
quantity       number of product units
page           page number requested by the client
size           number of products per page requested by the client
totalElements  total number of product types in the database (for pagination convenience)
totalPages     number of pages in the database (at the current size)

API for Java client

import javax.annotation.Nullable;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.UUID;

/**
 * API сервиса Продукты
 */
interface ProductApi {

    /**
     * Метод для создания бронирования на определенное количество продуктов (до оплаты)
     * Бронирование выполняется атомарно - либо для всех продуктов вместе, либо ни для одного
     *
     * @param request запрос для создания бронирования
     * @return статус созданного бронирования
     */
    ReservationCreatedResponse createReservation(ReservationCreateRequest request);

    /**
     * Метод для подтверждения бронирования (после оплаты)
     *
     * @param request запрос для подтверждения бронирования
     * @return статус подтвержденного бронирования
     */
    ReservationConfirmedResponse confirmReservation(ReservationConfirmRequest request);


    /**
     * Метод для отмены бронирования
     *
     * @param request запрос для отмены бронирования
     * @return статус отмененного бронирования
     */
    ReservationCancelledResponse cancelReservation(ReservationCancelRequest request);
}

class ReservationCreateRequest {

    /**
     * Список продуктов для бронирования
     */
    @NotEmpty
    List<ProductReservation> reservations;
}

class ProductReservation {

    /**
     * ID продукта для бронирования
     */
    @NotNull
    UUID productId;

    /**
     * Количество продукта для бронирования
     */
    @NotNull
    Integer reservedQuantity;
}


class ReservationCreatedResponse {

    /**
     * Статус созданного бронирования,
     * true  - успешно
     * false - неуспешно
     */
    @NotNull
    Boolean status;

    /**
     * Код ошибки в случае неуспешного создания бронирования {@link ReservationCreatedResponse#status}
     */
    @Nullable
    ReservationErrorCode errorCode;

    /**
     * ID созданного бронирования,
     * null - если забронировать не вышло
     */
    @Nullable
    UUID reservationId;

    /**
     * Время создания бронирования, если успешно {@link ReservationCreatedResponse#status}
     */
    @Nullable
    Instant reservationCreatedAt;

    /**
     * Количество времени в течении которого созданное бронирование действительно
     */
    @Nullable
    Duration reservationTimeout;

    /**
     * Список продуктов, которых недостаточно на складе с указанием оставшегося количества,
     * пустой список [] - если все бронирование успешно
     */
    @NotNull
    List<FailedProductReservation> failedReservations;
}

class FailedProductReservation {

    /**
     * ID продукта которого недостаточно на складе для бронирования
     */
    @NotNull
    UUID insufficientProductId;

    /**
     * Актуальное количество этого продукта на складе
     */
    @NotNull
    Integer actualQuantity;
}


class ReservationConfirmRequest {

    /**
     * ID созданного бронирования {@link ReservationCreatedResponse#reservationId}
     */
    @NotNull
    UUID reservationId;
}

class ReservationConfirmedResponse {

    /**
     * Статус подтвержденного бронирования,
     * true  - успешно
     * false - неуспешно
     */
    @NotNull
    Boolean status;

    /**
     * Код ошибки в случае неуспешного подтверждения бронирования {@link ReservationConfirmedResponse#status}
     */
    @Nullable
    ReservationErrorCode errorCode;
}

class ReservationCancelRequest {

    /**
     * ID созданного бронирования {@link ReservationCreatedResponse#reservationId}
     */
    @NotNull
    UUID reservationId;
}

class ReservationCancelledResponse {

    /**
     * Статус отмененного бронирования,
     * true  - успешно
     * false - неуспешно
     */
    @NotNull
    Boolean status;

    /**
     * Код ошибки в случае неуспешной отмены бронирования {@link ReservationCancelledResponse#status}
     */
    @Nullable
    ReservationErrorCode errorCode;
}

enum ReservationErrorCode {

    OUT_OF_STOCK("Продукта нет или недостаточно на складе"),
    INVALID_RESERVATION_ID("ID бронирования отсутствует в системе бронирования"),
    RESERVATION_TIMEOUT_EXPIRED("Таймаут для бронирования истек");
    private final String errorMessage;
    ReservationErrorCode(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}