Czy istnieją standardy lub najlepsze praktyki dotyczące strukturyzacji odpowiedzi JSON z interfejsu API? Oczywiście dane każdej aplikacji są inne, więc nie przejmuję się tym, ale raczej „odpowiedzią”, jeśli wolisz. Przykład tego, co mam na myśli:
Pomyślna prośba:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
Nieudane żądanie:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
Odpowiedzi:
Tak, pojawiło się kilka standardów (aczkolwiek pewne swobody w zakresie definicji normy):
Istnieją również formaty opisu API JSON:
źródło
Przewodnik Google JSON
Powrót odpowiedzi powodzenia
data
Zwrot odpowiedzi błędu
error
a jeśli Twoim klientem jest JS, możesz użyć,
if ("error" in response) {}
aby sprawdzić, czy wystąpił błąd.źródło
error
, strona Google podaje przykład tegoWydaje mi się, że standard defacto tak naprawdę nie pojawił się (i może nigdy). Ale niezależnie od tego, oto moje zdanie:
Pomyślna prośba:
Nieudane żądanie:
Zaleta: Te same elementy najwyższego poziomu zarówno w przypadku sukcesu, jak i błędu
Wada: brak kodu błędu, ale jeśli chcesz, możesz zmienić status na kod (sukces lub niepowodzenie) lub - możesz dodać kolejny element najwyższego poziomu o nazwie „kod”.
źródło
messages
która jest tablicą komunikatów zamiast jednego łańcucha.fail
dla typowych problemów z sprawdzaniem poprawności, podczas gdyerror
jest używany tylko w przypadku krytycznych błędów, takich jak błędy db.200
w nagłówkach, dlaczego potrzebujeszstatus
pola? po prostu zwróć obiekt danych prosto. Wiesz, że może to powodować dodatkowy ból przy pisaniu języków FE, takich jak TypeScript.Zakładając, że Twoje pytanie dotyczy projektu usług REST, a dokładniej sukcesu / błędu.
Myślę, że istnieją 3 różne rodzaje projektów.
Użyj tylko kodu stanu HTTP, aby wskazać, czy wystąpił błąd, i spróbuj ograniczyć się do standardowych (zwykle powinno wystarczyć).
Użyj stanu HTTP + treści Json (nawet jeśli jest to błąd). Zdefiniuj jednolitą strukturę dla błędów (np. Kod, komunikat, przyczynę, typ itp.) I użyj jej dla błędów, jeśli to się powiedzie, po prostu zwróć oczekiwaną odpowiedź JSON.
Zapomnij o statusie http (np. Zawsze status 200), zawsze używaj json i dodaj w katalogu głównym odpowiedzi boolean responseValid i obiekt błędu (kod, komunikat itp.), Który zostanie wypełniony, jeśli jest to błąd, w przeciwnym razie pozostałe pola (sukces) są wypełnione.
Plusy: klient zajmuje się tylko treścią, która jest łańcuchem JSON i ignoruje status (?).
Minusy: mniej standardowy.
Wybór należy do ciebie :)
W zależności od API wybrałbym 2 lub 3 (wolę 2 dla json rest apis). Kolejną rzeczą, której doświadczyłem przy projektowaniu REST Api, jest znaczenie dokumentacji dla każdego zasobu (adresu URL): parametry, treść, odpowiedź, nagłówki itp. + Przykłady.
Poleciłbym również użyć jersey (implementacja jax-rs) + genson (biblioteka wiązania danych java / json). Musisz tylko upuścić genson + koszulkę na ścieżkę klasy, a Json jest automatycznie obsługiwany.
EDYTOWAĆ:
Rozwiązanie 2 jest najtrudniejsze do wdrożenia, ale zaletą jest to, że możesz ładnie obsługiwać wyjątki i nie tylko błędy biznesowe, początkowy wysiłek jest ważniejszy, ale wygrywasz w perspektywie długoterminowej.
Rozwiązanie 3 jest łatwe do zaimplementowania zarówno po stronie serwera, jak i klienta, ale nie jest tak przyjemne, ponieważ będziesz musiał obudować obiekty, które chcesz zwrócić, w obiekcie odpowiedzi zawierającym również błąd responseValid +.
źródło
RFC 7807: Problem Szczegóły HTTP API jest w tej chwili najbliższą rzeczą mamy do oficjalnego standardu.
źródło
Poniżej znajduje się instagram w formacie json
źródło
Nie będę aż tak arogancki, twierdząc, że jest to standard, więc użyję formularza „Wolę”.
Wolę krótką odpowiedź (przy żądaniu listy / artykułów chcę tablicę artykułów JSON).
W moich projektach używam HTTP do raportowania stanu, 200 zwraca tylko ładunek.
400 zwraca komunikat o tym, co było nie tak z żądaniem:
Zwróć 404, jeśli model / kontroler / URI nie istnieje
Jeśli wystąpił błąd przetwarzania po mojej stronie, zwracam 501 z komunikatem:
Z tego, co widziałem, całkiem sporo ram REST jest podobnych.
Racjonalne uzasadnienie :
JSON ma być formatem ładunku , nie jest protokołem sesji. Cały pomysł pełnych sesji sesji pochodzi ze świata XML / SOAP i różnych błędnych wyborów, które stworzyły te rozdęte projekty. Po tym, jak zdaliśmy sobie sprawę, że to wszystko było ogromnym bólem głowy, cały sens REST / JSON polegał na pocałowaniu go i przestrzeganiu protokołu HTTP. Nie sądzę, że w JSend jest coś zdalnie standardowego, a zwłaszcza że nie ma wśród nich więcej gadatliwości. XHR zareaguje na odpowiedź HTTP, jeśli użyjesz jQuery dla swojego AJAX (jak większość), możesz użyć
try
/catch
idone()
/fail()
callback do przechwytywania błędów. Nie widzę, jak enkapsulowanie raportów o stanie w JSON jest bardziej przydatne niż to.źródło
Dla tego, co warto, robię to inaczej. Pomyślne wywołanie zawiera tylko obiekty JSON. Nie potrzebuję obiektu JSON wyższego poziomu, który zawiera pole powodzenia wskazujące wartość true oraz pole ładunku zawierające obiekt JSON. Zwracam tylko odpowiedni obiekt JSON z wartością 200 lub cokolwiek odpowiedniego w zakresie 200 dla statusu HTTP w nagłówku.
Jeśli jednak wystąpi błąd (coś w rodzinie 400), zwracam dobrze sformułowany obiekt błędu JSON. Na przykład, jeśli klient POST wysyła do użytkownika adres e-mail i numer telefonu, a jeden z nich jest zniekształcony (tzn. Nie mogę go wstawić do bazy danych), zwrócę coś takiego:
Ważne są tutaj bity, że właściwość „field” musi dokładnie pasować do pola JSON, czego nie można zweryfikować. To pozwala klientom dokładnie wiedzieć, co poszło nie tak z ich żądaniem. Ponadto „wiadomość” znajduje się w ustawieniach regionalnych żądania. Gdyby zarówno adres „emailAddress”, jak i „phoneNumber” były nieprawidłowe, tablica „error” zawierałaby wpisy dla obu. Ciało odpowiedzi JSON 409 (konflikt) może wyglądać następująco:
Dzięki kodowi stanu HTTP i temu JSON klient ma wszystko, czego potrzeba, aby reagować na błędy w sposób deterministyczny i nie tworzy nowego standardu błędów, który próbuje uzupełnić kody stanu HTTP. Uwaga: zdarzają się one tylko w zakresie 400 błędów. Za wszystko z zakresu 200 mogę po prostu zwrócić wszystko, co jest odpowiednie. Dla mnie często jest to obiekt JSON podobny do HAL, ale tutaj tak naprawdę nie ma to znaczenia.
Jedyną rzeczą, o której pomyślałem o dodaniu, był numeryczny kod błędu albo we wpisach tablicy „błędy”, albo w samym rdzeniu samego obiektu JSON. Ale do tej pory nie potrzebowaliśmy tego.
źródło
Nie ma zgody na pozostałe formaty odpowiedzi API wielkich gigantów oprogramowania - Google, Facebook, Twitter, Amazon i inne, chociaż w powyższych odpowiedziach podano wiele linków, w których niektórzy próbowali ujednolicić format odpowiedzi.
Ponieważ potrzeby interfejsów API mogą się różnić, bardzo trudno jest zdobyć wszystkich na pokładzie i zgodzić się na jakiś format. Jeśli masz miliony użytkowników korzystających z interfejsu API, dlaczego miałbyś zmienić format odpowiedzi?
Oto moje zdanie na temat formatu odpowiedzi zainspirowanego przez Google, Twitter, Amazon i niektóre posty w Internecie:
https://github.com/adnan-kamili/rest-api-response-format
Plik swagger:
https://github.com/adnan-kamili/swagger-sample-template
źródło
Chodzi o to, że JSON jest całkowicie dynamiczny i elastyczny. Wygnij to, co tylko zechcesz, ponieważ jest to tylko szereg zserializowanych obiektów i tablic JavaScript, zakorzenionych w jednym węźle.
To, jaki typ węzła root zależy od Ciebie, co on zawiera, zależy od Ciebie, niezależnie od tego, czy wyślesz metadane wraz z odpowiedzią, niezależnie od tego, czy ustawisz typ MIME na,
application/json
czy też pozostawisz to, cotext/plain
zależy od Ciebie ( tak długo, jak wiesz, jak obsługiwać skrzynki krawędziowe).Zbuduj lekki schemat, który Ci się podoba.
Osobiście odkryłem, że śledzenie i analityki mp3 / ogg serwowania i galeria obrazów i tekstu obsługujących wiadomości i network-pakiety dla gier online, a blog-posty i komentarze blog- wszyscy mają bardzo różne wymagania , jeśli chodzi o to, co jest wysłane, co zostało odebrane i jak należy je spożywać.
Ostatnią rzeczą, której chciałbym, robiąc to wszystko, jest, aby każdy z nich był zgodny z tym samym standardem opartym na XML2.0 lub jakimś innym.
To powiedziawszy, jest wiele do powiedzenia na temat korzystania ze schematów, które mają dla ciebie sens i są dobrze przemyślane.
Po prostu przeczytaj odpowiedzi API, zanotuj to, co lubisz, skrytykuj to, czego nie robisz, zanotuj te krytyki i zrozum, dlaczego źle cię pocierają, a następnie zastanów się, jak zastosować to, czego nauczyłeś się, czego potrzebujesz.
źródło
JSON-RPC 2.0 definiuje standardowy format żądania i odpowiedzi oraz powiew świeżości po pracy z interfejsami API REST.
źródło
code
pole było ciągiem. Na szczęście specyfikacja pozwala nam umieścić dowolne informacje w polu błędudata
. W moich projektach JSON-RPC zwykle używam jednego kodu numerycznego dla wszystkich błędów warstwy aplikacji (w przeciwieństwie do jednego ze standardowych błędów protokołu). Następnie umieszczam szczegółowe informacje o błędzie (w tym kod ciągu wskazujący prawdziwy typ błędu) wdata
polu.Dla tych, którzy przyjdą później, oprócz zaakceptowanej odpowiedzi, która obejmuje HAL, JSend i JSON API, dodam kilka innych specyfikacji, które warto zbadać:
źródło
Sugerowana podstawowa struktura wygląda dobrze, ale zdefiniowany obiekt błędu jest zbyt ograniczony. Często nie można użyć jednej wartości do wyrażenia problemu, a zamiast tego potrzebny jest łańcuch problemów i przyczyn .
Zrobiłem trochę badań i odkryłem, że najczęstszym formatem zwracania błędów (wyjątków) jest struktura tej formy:
Jest to format zaproponowany przez standard danych OASIS ODAS OASIS i wydaje się być najbardziej standardową opcją, jednak wydaje się, że w tym momencie nie ma wysokich wskaźników adopcji. Ten format jest zgodny ze specyfikacją JSON-RPC.
Kompletną bibliotekę open source, która to implementuje, można znaleźć na stronie: Mendocino JSON Utilities . Ta biblioteka obsługuje obiekty JSON, a także wyjątki.
Szczegóły omówiono w moim blogu na temat obsługi błędów w JSON REST API
źródło
Nie ma innego standardu łamania prawa lub zakazania prawa niż zdrowy rozsądek. Jeśli streszczymy to tak, jak rozmawiają dwie osoby, standard jest najlepszym sposobem, w jaki mogą dokładnie się zrozumieć przy użyciu minimalnych słów i czasu. W naszym przypadku „minimalne słowa” optymalizują przepustowość pod kątem wydajności transportu, a „dokładnie rozumiem” to strukturę wydajności analizatora składni; co ostatecznie kończy się mniejszą ilością danych i wspólną strukturą; aby mógł przejść przez otwór na szpilkę i zostać przeanalizowany przez wspólny zakres (przynajmniej początkowo).
Niemal we wszystkich sugerowanych przypadkach widzę osobne odpowiedzi na scenariusz „Sukces” i „Błąd”, co jest dla mnie niejasnością. Jeśli odpowiedzi są różne w tych dwóch przypadkach, to dlaczego naprawdę musimy umieścić tam flagę „Sukces”? Czy nie jest oczywiste, że brak „błędu” to „sukces”? Czy możliwe jest uzyskanie odpowiedzi, w której „Sukces” jest PRAWDĄ, przy ustawionym „Błędzie”? Czy też sposób, w jaki „Sukces” jest FAŁSZ bez ustawionego „Błąd”? Tylko jedna flaga to za mało? Wolałbym mieć tylko flagę „Błąd”, ponieważ uważam, że będzie mniej „Błąd” niż „Sukces”.
Czy naprawdę powinniśmy ustawić flagę „Błąd”? Co jeśli chcę odpowiedzieć wieloma błędami weryfikacji? Uważam więc, że bardziej wydajne jest posiadanie węzła „Błąd” z każdym błędem jako potomka tego węzła; gdzie pusty (liczony do zera) węzeł „Błąd” oznaczałby „sukces”.
źródło
Najlepsza odpowiedź na api internetowe, które mogą łatwo zrozumieć programiści mobilni.
Dotyczy odpowiedzi „Sukces”
Dotyczy odpowiedzi „Błąd”
źródło