Jest jeszcze drugie podejście, może zaraz pojawić się mocna gównoburza, ale napiszę. Część ludzi uważa, że to jest dobre, część że to prowizorka i masakryczna zbrodnia ;)
Ogólnie w takiej sytuacji, jeśli komunikacja z serwerem poszła OK, to dajesz ZAWSZE kod 200 - bo oznacza, że żądanie zostało przetworzone pozytywnie, udało się dobić do serwera, on zrozumiał o co chodzi, przetworzył (w jakikolwiek sposób) żądanie, wysłał odpowiedź. A szczegóły odnośnie tego, co serwer ma do przekazania na front (albo gdziekolwiek indziej - np. do aplikacji mobilnej) przesyłasz wewnątrz odpowiedzi - czy jakiś JSON, czy jakkolwiek inaczej zapakowane.
Nie chcę teraz nikogo triggerować, wiem że wiele osób uważa to za coś gorszego od rasizmu i nazizmu, ale w sumie... to Twoja apka, Ty decydujesz jak zrobisz. Jeśli Tobie takie coś pasuje to jedź śmiało. Dla mnie takie podejście jest OK - status HTTP oznacza tylko tyle, że moje zapytanie dotarło do serwera i zostało przetworzone, a co serwer konkretnie miał do przekazania mam już w treści/ciele odpowiedzi.
To trochę jak z pismem z odpowiedzią z urzędu - dostajesz list w kopercie (czyli odpowiednik otrzymania kodu 200), a w środku koperty jest dokument, którego treść jest właściwą odpowiedzią na złożone zapytanie. Możesz dostać zarówno zgodę na to, o co wnioskowałeś (czyli odpowiednik kodu 200), odmowę (czyli np. 403) albo wezwanie do złożenia wyjaśnień/uzupełnienia braków (odpowiednik kodu np. 300). Plusem jest też to, że w takim wariancie nie musisz się ograniczać i dopasowywać do istniejących kodów http, ale stworzyć swoje odpowiedzi, które będą dokładnie dopasowane do tego, czego potrzebujesz - dokładnie tak, jak wynika to z logiki działania aplikacji. A później, jeśli pojawi się potrzeba dodania nowego scenariusza/innego zachowania, to po porostu dodajesz kolejny wariant.
