2014-12-14 14 views
7

Należy rozważyć metodę interfejsu API WWW, która nie ma skutków ubocznych, ale pobiera dane binarne jako parametr. Przykładem może być metoda informująca użytkownika o tym, czy jego zdjęcie zostało sfotografowane, ale nie przechowująca na stałe obrazu ani wyniku na swoich serwerach.Prawidłowa metoda żądania HTTP dla akcji eliminującej ruch, która pobiera dane binarne

Czy taką metodą powinien być GET lub POST?

GET nie ma zalecanego sposobu wysyłania danych poza parametry URL, ale zachowanie metody implikuje GET, który zgodnie ze specyfikacją HTTP służy do bezpiecznych, bezpaństwowych odpowiedzi. Staje się to szczególnie ograniczone w ramach semantyki REST, co oznacza, że ​​metody tworzą nowy obiekt na serwerze.

Odpowiedz

4

Staje się to szczególnie restrykcyjne w ramach semantyki REST, co oznacza, że ​​metody POST tworzą nowy obiekt na serwerze.

Choć wniosek POST oznacza, że ​​podmiot wysłane będą traktowane „jako nowego podwładnego zasobu wskazanego przez URI-”, nie ma wymogu, że wynik ten w tworzeniu nowej stałego obiekt lub że dowolny taki nowy obiekt może być identyfikowany przez URI (więc nie ma nowego obiektu, o ile klient wie). Obiekt może być przejściowy, reprezentujący wyniki np. "Dostarczenie bloku danych, na przykład wyniku przesłania formularza, do procesu przetwarzania danych" i nie będzie trwało po wysłaniu obiektu reprezentującego ten obiekt.

Chociaż oznacza to, że POSTmoże utworzyć nowy zasób, i jest z pewnością najlepszym sposobem, aby to zrobić, gdy jest to serwer, który zapewni, że nowy zasób jego URI (z PUT będąc bardziej odpowiedni sposób, gdy klient dyktuje nowy URI), można go również używać do przypadków, które usuwają obiekty (choć ponownie, jeśli jest to usunięcie pojedynczego * zasobu identyfikowalnego przez URI, wtedy DELETE jest o wiele bardziej odpowiedni), zarówno tworzyć, jak i usuwać obiekty, zmieniać wiele obiektów może to oznaczać, że światło w kuchni włącza się, ale odpowiedź jest taka sama, niezależnie od tego, czy zadziałało, czy nie, ponieważ komunikacja z serwera WWW do światła kuchni nie pozwala na uzyskanie opinii o sukcesie. To naprawdę może zrobić cokolwiek.

Ale twoje instynkty są dobre w chcąc to być GET: Gdy luz z POST oznacza, że ​​możemy złożyć sprawę do niej na prawie każde życzenie (jak zrobione przez podejść, które korzystają z protokołu HTTP do protokołu RPC-like , zasadniczo traktując HTTP tak, jakby był protokołem transportowym), jest to nieeleganckie w teorii, nieskuteczne w praktyce i niezdarne w definicji. Masz idempotentną funkcję, która zależy wyłącznie od tego, co interesuje klienta, i która w oczywisty sposób mapuje numer GET na kilka sposobów.

Gdybyśmy mogli zmieścić wszystko w URI, to byłoby łatwe łatwe GET. Np. Możemy zdefiniować proste dodawanie liczb całkowitych z czymś takim, jak http://example.net/addInts?x=1;y=2 reprezentującym dodanie 71 i 2, a tym samym będąc stałym niezmiennym zasobem reprezentującym liczbę 3 (ponieważ wyniki GET mogą się zmieniać wraz ze zmianami zasobu w czasie, ale ten zasób nigdy zmiany), a następnie użyj mechanizmu, takiego jak kod HTML <form> lub javascript, aby umożliwić serwerowi poinformowanie klienta o tym, jak zbudować identyfikatory URI dla innych numerów (aby zachować ograniczenia HATEOS i/lub COD). Simples!

Twój problem polega na tym, że nie masz danych wejściowych, które można przedstawić tak zwięźle, jak numery powyżej 1 i 2. Teoretycznie można zrobić coś takiego, jak http://example.net/photoshoppedCheck?image=data:image/png;base64,iVBORw0KGgoAAAANSU…, a zatem utworzyć identyfikator URI, który reprezentuje zasób wyników kontroli. Ten identyfikator URI będzie jednak miał 4 znaki na każde 3 bajty w obrazie. Chociaż nie ma bezwzględnego ograniczenia długości URI, zarówno teoria, jak i praktyka pozwalają na niepowodzenie (teoretycznie HTTP zezwala serwerom i proxy na ustalanie limitu długości URI, aw praktyce tak właśnie się dzieje).

Można argumentować za używaniem GET i wysyłanie treści żądania w taki sam sposób, jak w przypadku POST, a niektóre serwery internetowe pozwalają nawet na to. Jednakże, GET jest zdefiniowany jako zwracanie encji opisującej zasób zidentyfikowany w URI z nagłówkami ograniczającymi sposób, w jaki ta jednostka robi, która opisująca: Ponieważ treść żądania nie jest częścią tej definicji, musi być ona zignorowana przez twój kod! Jeśli miałeś skłonność do zginania tej reguły, musisz wziąć pod uwagę następujące informacje:

  1. Niektóre serwery internetowe odmówią wykonania żądania lub pozbędzieją się ciała, więc możesz nie być w stanie.
  2. Jeśli twój serwer sieciowy na to zezwala, fakt, że nie jest określony, oznacza, że ​​nie możesz być pewien uaktualnienia, nie "naprawi" tego, a więc złamie twój kod.
  3. Niektórzy programiści odrzucą lub usuną żądanie.
  4. Niektóre biblioteki klienta z pewnością nie pozwalają programistom na wysyłanie treści żądania wraz z GET.

To nie jest nie w teorii i praktyce.

Jedynym innym podejściem, jakie możemy zrobić, poza POST, jest posiadanie identyfikatora URI, który uważamy za reprezentujący obraz, który nie został zeskanowany photoshopem. Stąd, jeśli dostaniesz podmiot opisujący obraz (oczywiście może to być rzeczywisty obraz, choć może to być również coś innego, jeśli rozwiniemy koncepcję negocjacji treści), a następnie PUT sprawdzi obraz i jeśli zostanie on uznany za nie można go przerobić na photoshopa, odpowiada tym samym obrazem i 200 lub po prostu 204, natomiast jeśli jest on zapisany w photoshopie, odpowiada on na 400, ponieważ próbowaliśmy wykonać zdjęcie z użyciem photoshopped jako zasób, który może być tylko niefotografowany obraz. Ponieważ reagujemy natychmiast, nie ma warunków wyścigowych z jednoczesnymi żądaniami.

Szczerze mówiąc, byłoby to okropne. Chociaż wydaje mi się, że przytoczyłem uzasadnienie listem specyfikacji, jest to po prostu nieprzyjemne: REST ma pomóc nam w projektowaniu przejrzystych interfejsów API, a nie rozwlekłych interfejsów API, które możemy zaoferować zbyt sprytnie-dla-własnego-dobra. uzasadnienie.

Nie, w całości, aby przejść tutaj, jest POST obraz do stałego URI, który następnie zwraca prostą jednostkę opisującą analizę.

Jest to całkowicie uzasadnione, jako REST (POST tworzy obiekt przejściowy oparty na tym obrazie, a następnie odpowiada za pomocą obiektu opisującego ten obiekt, a następnie obiekt ten ponownie znika). To proste. Jest prawie tak wydajny, jak tylko może być (nie możemy zrobić żadnego buforowania HTTP †, ale większość opóźnienia sieci będzie w dalszym ciągu przesyłana, a nie pobierana). Pasuje również do ogólnego zastosowania "procesu coś", dla którego został wymyślony po raz pierwszy. (Pamiętaj, że najpierw był HTTP, a REST opisał, dlaczego tak dobrze działało, a następnie poprawiono HTTP, aby lepiej grać na tych mocnych stronach).

W sumie, podczas gdy klasyczny błąd, który porusza aplikację internetową od reszta jest nadużywanie POST się robi absolutnie wszystko, gdy GET, PUT i DELETE (a może metody WebDAV) byłby lepszy, nie bój się używaj jego mocy, gdy ci nie spełniają ustawy, i nie myśl, że "nowy podwładny zasobu" musi oznaczać pełne, długo żyjące zasoby.


* Należy pamiętać, że „single” zasób tutaj może składać się z kilku środków, które mogą mieć własne URI, dzięki czemu może być łatwo mieć jeden DELETE która usuwa wiele obiektów, ale jeśli usuwania X Usuwa , B & C, to lepiej być oczywistym, że nie możesz mieć A, B lub C, jeśli nie masz X lub twoje API nie będzie zrozumiałe. Zasadniczo sprowadza się to do tego, co jest modelowane i jak oczywiste jest to, że jedna rzecz zależy od drugiej.

† Ściśle mówiąc możemy, ponieważ możemy wysyłać nagłówki pamięci podręcznej wskazujące, że wysyłanie identycznego obiektu do tego samego identyfikatora URI będzie miało takie same wyniki, ale nie ma żadnego ogólnego oprogramowania internetowego, które to zrobi i niestandardowy klient może mimo wszystko "zapamiętać" opinię o samym obrazie.

1

To jest trudne. Podobnie jak w przypadku wielu innych scenariuszy, nie ma absolutnie poprawnego sposobu robienia tego. Trzeba spróbować interpretować RESTful zasady w odniesieniu do ograniczeń semantyki HTTP. (Nawiasem mówiąc, nie sądzę, że słuszne jest myślenie o REST z semantyką, REST jest stylem architektonicznym, który jest powszechnie używany z usługami HTTP, ale może być używany dla dowolnego typu interfejsu.)

Mam do czynienia z podobna sytuacja w moim obecnym projekcie. Wybraliśmy opcję POST, ale kod odpowiedzi to 200 (OK), a nie 201 (utworzone zasoby) zwykle zwracane przez interfejsy API usług RESTful Web.