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:
Żądanie:
PUT /zasób-biznesowy/{identyfikator-zasobu}/{typ-polecenia}-commands/{identyfikator-polecenia-uuid}
Body:
{
// dane wejściowe właściwe dla polecenia np.:
“input”: {
"buyNowPrice": {
"amount": "122",
"currency": "PLN"
}
}
}
Odpowiedź:
201 Created
{
“id”: “9b84e1bc-5341-45e7-837e-4250720e606f”,
“input”: {
"buyNowPrice": {
"amount": "122",
"currency": "PLN"
}
},
“output”: {
"status" : "RUNNING",
"errors" : []
// inne dane zwrotne odpowiednie dla tego polecenia
}
}
Dla przykładu zasób pozwalający na wykonanie operacji zmiany ceny:
PUT /offers/12345/change-price-commands/84c16171-233a-42de-8115-1f1235c8bc0f
Wykonując żądanie na powyższy zasób - do kolekcji czynności mających się wykonać na ofercie wskazanej przez identyfikator = 12345, dokładamy polecenie zmiany ceny o identyfikatorze 84c16171-233a-42de-8115-1f1235c8bc0f.
Należy zwrócić uwagę, że w przypadku tych zasobów używamy metody http PUT, a nie POST. Co oznacza, że to klient wskazuje (przesyła) identyfikator pod jakim będzie figurowało zgłoszone polecenie
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.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Specyfikacja RFC UUID: http://www.ietf.org/rfc/rfc4122.txt