Cześć. Jaki macie sposób na mapowanie klas z vavra w restach ? Zwracacie bezpośrednio i po stronie klienta czytacie to co jest np w right/left w przypadku either czy piszecie jakiś własny resolver do tego, żeby ustawić kod odpowiedzi i zwracacie ResponseEntity ?
https://github.com/vavr-io/vavr-jackson
załatwia sprawe, zwykle jakoś do ObjectMappera trzeba zarejestrować.
Jak klepiesz w springu :-( to np. tak:
https://stackoverflow.com/questions/46285615/serializer-deserializer-for-vavr-objects
Tak, to już mam, tylko np either zwraca mi w takiej postaci:
["right",{"a":"s1","b":"s2"}]
lub
["left",{"message":"Jakis err"}]
A chciałbym bezpośrednio dostać {"a":"s1","b":"s2"} lub {"message":"Jakis err"}
Napisałem sobie resolver, ale nie wiem czy to prawilne rozwiązanie:
public class ResponseResolver {
private final static Map<ErrorCode, HttpStatus> HTTP_STATUS_MAP =
HashMap.of(
ErrorCode.USER_NOT_FOUND, HttpStatus.NOT_FOUND,
ErrorCode.USER_EMPTY_REQUIRED_DATA, HttpStatus.BAD_REQUEST
);
public <T> ResponseEntity<Object> resolve(Either<? extends AppError, T> either) {
return either
.map(this::createObject)
.getOrElseGet(this::createError);
}
private ResponseEntity<Object> createObject(Object object) {
return new ResponseEntity<>(object, HttpStatus.OK);
}
private ResponseEntity<Object> createError(AppError error) {
return new ResponseEntity<>(error, HTTP_STATUS_MAP.getOrElse(error.getErrorCode(), HttpStatus.BAD_REQUEST));
}
}
No bo użycie Eithera jest takie że albo masz bląd albo OK, więc ja bym zrobił coś stylu if (either.isRight()) zwróc Reponse Entity z okejką i body, else zwróc błąd i ew. jakieś body
Bardzo podobnych resolverów używam (tylko nie w springu).
Dzięki, o taki response mi chodziło :)
Też chciałem spróbować ten VAVR i mam podobny problem, tylko, że mi się nie podoba ResponseEntity<Object>/ResponseEntity<?>. Próbowałem z Try, ale wywala się na serializacji (tylko przy success, przy error jest ok):
JsonMappingException: getCause on Success (through reference chain: io.vavr.control.Try$Success['cause'])
Dodatkowo w VavrSerializers nie widzę nic zwiazanego z Try, czy Try nie powinno się używać w ten sposób i ja tu jakieś herezje tworze?:D
Dodałem swój TrySerializer i działa, ale skoro Vavr nie dostarczył swojego to raczej mieli w tym jakiś cel.
Co do tego Try - to do czego miałby on serializować jeśli wynikiem jest error ?
Tak jak w Either jest either.isLeft() ? write(either.getLeft()) : write(either.getRight())
tak w Try mogłoby być try.isSuccess() ? write(try.get()) : write(try.getCause())
.
Generalnie chyba źle rozumiem ideę Try, traktuje to jako coś w stylu Either<Throwable, T> a to chyba jednak coś więcej.
Może problem jest w tym, że przeważnie takiego getCause jako wyniku się nie robi. Daje sie odpowiedni http status, na produkcji nie pokazuje sie cause, na dev zwykle pokazujesz stacktrace. Zbyt specyficzne IMO.
No właśnie, zwróciłbyś frontom NullPointera? xD Jak dla mnie jeśli Try ma błąd to wtedy zwracasz te 5xx i tyle ;] Ew. piszesz jakąs wiadomość dodatkowo, ale nie cause z Try :d