Czym jest wzorzec Command?
W REST API Allegro istnieją zasoby, które odzwierciedlają typowe operacje CRUD (ang. Create, Read, Update, Delete) i są one zmapowane na odpowiednie metody HTTP POST, GET, PUT, DELETE.
Obok takich zasobów, które są semantycznie proste, występują również zasoby, które odnoszą się do wykonania złożonych operacji lub określonych akcji w odniesieniu do obiektu (np. oferta, transakcja, użytkownik itp.).
Żądanie skierowane do takiego zasobu może wiązać się z wykonaniem kilku operacji po stronie platformy Allegro i/lub dokonaniem zmian w atrybutach obiektów; bądź też wywołuje określone biznesowe konsekwencje dla platformy Allegro (w tym zintegrowanych systemów) oraz użytkowników uczestniczących w danym procesie (wystawienie oferty, transakcja zakupowa). Przykłady takich operacji: "wstrzymanie i wznowienie oferty", "zmiana ceny Kup Teraz w aktywnej ofercie".
W przypadku takich operacji realizując RESTowe API zastosowany został wzorzec programistyczny Command.
Command jest operacyjnym wzorcem projektowym, którego celem jest enkapsulacja czynności do wykonania i ich parametrów. Wzorzec ten określa polecenie jako obiekt, który jest wysyłany od klienta do odbiorcy, co pozwala nam na takie funkcjonalności jak: kolejkowanie poleceń, kontrolowanie historii (nawet z operacją ‚undo’) i temu podobne.
Konstrukcja takich zasobów w przypadku Allegro REST API wygląda następująco:
- W przypadku metody PUT, gdzie klient samodzielnie przesyła identyfikator polecenia:
Przykładowe żądanie zmiany ceny:
PUT /sale/offer-price-change-commands/{identyfikator-polecenia-uuid}
Body:
{
// dane wejściowe właściwe dla polecenia np.:
"modification": {
"type": "FIXED_PRICE",
"marketplaceId": "allegro-pl",
"price":{
"amount": "100",
"currency": "PLN"
}
},
"offerCriteria": [
{
"offers": [
{
"id": "123456789"
}
],
"type": "CONTAINS_OFFERS"
}
]
}
Odpowiedź:
201 Created
{
"id": "{identyfikator-polecenia-uuid}",
"createdAt": "2019-08-24T14:15:22Z",
"completedAt": "2019-08-24T14:15:22Z",
"taskCount": {
"failed": 0,
"success": 0,
"total": 0
}
}
- W przypadku metody POST, gdzie klient nie musi wskazywać identyfikatora polecenia (wygenerujemy do automatycznie w odpowiedzi w takim przypadku), ale może wskazać go opcjonalnie w body żądania:
Przykładowe żądanie dla przypisania reguły cenowej do oferty:
POST /sale/offer-price-automation-commands
Body:
{
"id": "{opcjonalny-identyfikator-polecenia-uuid}",
"modification": {
"set": [
{
"marketplace": {
"id": "allegro-pl"
},
"rule": {
"id": "641c73feaef0a8281a3d11f8"
},
"configuration": {
"priceRange": {
"type": "MARKETPLACE_CURRENCY",
"minPrice": {
"amount": "100.45",
"currency": "PLN"
},
"maxPrice": {
"amount": "233.21",
"currency": "PLN"
}
}
}
}
]
},
"offerCriteria": [
{
"offers": [
{
"id": "123456789"
}
],
"type": "CONTAINS_OFFERS"
}
]
}
Odpowiedź:
{
"id": "{identyfikator-polecenia-uuid}",
"createdAt": "2019-08-24T14:15:22Z",
"completedAt": "2019-08-24T14:15:22Z",
"taskCount": {
"failed": 0,
"success": 0,
"total": 0
}
}
W celu zapewnienia, że przesyłany od klienta w żądaniu identyfikator polecenia jest unikatowy wymagane są identyfikatory w standardzie UUID.
Zastosowanie
Co daje zastosowanie takiego wzorca?
standaryzowany sposób deklaracji wykonania operacji - otrzymujemy jednolite API, a wszystkie złożone operacje wykonujemy na zasobach, które zrealizowane są w taki sam sposób - mamy czynność do wykonania i parametry;
standardowy mechanizm śledzenia statusu operacji asynchronicznych - obok zasobu wywoływanego metodą http PUT może istnieć zasób wywoływany poprzez metodę GET, który zwróci aktualny status przetwarzania polecenia;
wykonanie operacji w sposób idempotentny - metoda PUT jest idempotentna co oznacza, że każde ponowne żądanie powoduje aktualizację tego samego zasobu i nie zmienia wyniku.
Źródła
Polecenie - wzorzec projektowy: https://pl.wikipedia.org/wiki/Polecenie_(wzorzec_projektowy)
Specyfikacja RFC metody PUT protokołu HTTP: https://www.rfc-editor.org/rfc/rfc9110.html#name-put
Specyfikacja RFC metody POST protokołu HTTP: https://www.rfc-editor.org/rfc/rfc9110.html#name-post
Specyfikacja RFC UUID: http://www.ietf.org/rfc/rfc4122.txt