-
-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
After
handler to turn null
into 404
#3566
Comments
Signature for handler is:
So it must be non-null, but guess it depends on the encoder... Adding an after handler seems too much for me, user should never returns |
I agree with @jknack . It also begs the question of things like HTTP method How we deal with this is a custom return NotFoundException.throwIfNull(userRepository.findUserById(userId)); |
With @agentgt Nice tip with the custom exception, I'll make a note of it, thanks! I agree that Maybe even with some configuration options, bc sometimes |
How bad is to add method like @agentgt suggest to StatusCode? return StatusCode.NOT_FOUND.throwIfNull(userRepository.findUserById(userId)) Also: Or probably |
Yeah, I guess we need something built-in for that. However, with I'd prefer more classic approach, like For MVC, we could also introduce corresponding annotations that automatically wrap responses in a
|
It doesn't. Look: class StatusCode {
<T> T throwIfNotnull(T value) {
if (value ==null) {
throw new StatusCodeException(this);
}
return value;
}
} So what ever: |
it is similar, but not the same from my point of view.
This style reads more declaratively as you're asking for a result and specifying an alternative if the result isn't available. It's closer to how you'd express business logic, it's more readable. But it requires some overhead due to the
This approach is more imperative and direct. It’s saying, “Here’s the resource; if it's null, throw an exception.” It is more focused on how things are done, which can be harder to read at a glance. The introduction of For me, readability and clarity prevail in this case, but this is just my point of view |
This is the That requires you return As far as more readable or declarative that is point of view. A Lisp programmer prefers right to left reading of code but I admit that is a weak argument. The real big thing is that But going back to return Optional.ofNullable(user).orElseThrow(NotFoundException::new); EDIT using @jknack notation (that avoids a ton of classes): return Optional.ofNullable(user).orElseThrow(StatusCode.NOT_FOUND::exception); |
I'm not trying to make Jooby be like Spring in any chance. You are absolutely right, this is just a syntactic sugar of the typical Nowadays with all these clouds and microservices developers produce tons of code per second, and we are spending more and more time reading/discovering the code rather than writing it. So when there is a little chance to make this reading process a bit simpler/faster for a developer I usually go for it. Do I like this The whole public class Result<T> {
private final T value;
private Result(T value) {
this.value = value;
}
public static <T> Result<T> of(T value) {
return new Result<>(value);
}
public T orElse(StatusCode code) {
if (value == null) {
throw new StatusCodeException(code);
}
return value;
}
public T orElse(StatusCode code, String message) {
if (value == null) {
throw new StatusCodeException(code, message);
}
return value;
}
} that's it, I didn't get about "ton of classes" BTW, Jooby 1.x had |
The ton of classes was loaded with multiple things. If we did the The other reason I mentioned ton of classes was to avoid an exception per status code which is what we have in our code base. The reason we have that is I try to make exceptions happen as close as possible to the error. That is I'm not even really a fan of That is this is awkward return Optional.ofNullable(user).orElseThrow(() -> new StatusCodeException(StatusCode.NOT_FOUND)); EDIT luckily though Jooby includes It really is not that unreadable: // Most people use `Optional` for service calls. I don't even like `Optional` and I use it for Service calls because many return `Stream` of something.
var user = findUser(userId);
return user.orElseThrow(NotFoundException::new); Now going back:
Is not the whole implementation and if it is it is not worth it. The Spring implementation is vastly superior and not because it is more complex but because it treats I'm not trying to be rude but willy nilly adding API for elegance just bloats shit. Jooby already has StatusCodeException StatusCode.exception()
// and maybe
StatusCodeException StatusCode.exception(String message) Which is a lot less than 4 or so classes to correctly implement a |
Also the Actually the above is a far bigger pain for us than dealing with You see before everyone built SPAs with RESTful backends the flow was this assuming a FORM post:
Like 90% of the web is still this way and that last step is painful in Jooby (well the validation was painful but there have been updates on that front). The last step is to avoid double submission. So if we did this BTW @jknack if you are curious how I handle @Override
public @Nullable DataBuffer render(
Context ctx,
ModelAndView modelAndView)
throws Exception {
if (!supports(modelAndView)) {
throw new IllegalStateException();
}
RedirectView rv;
if (modelAndView instanceof RedirectView _rv) {
rv = _rv;
}
public interface RedirectView {
public URI getRedirectUri();
default Set<RedirectFlag> getRedirectFlags() {
return EnumSet.noneOf(RedirectFlag.class);
}
default RedirectType getRedirectType() {
return RedirectType.FOUND;
}
public enum RedirectFlag {
CONTEXT_RELATIVE,
DISALLOW_RELATIVE;
public boolean isSet(
Set<RedirectFlag> flags) {
return flags.contains(this);
}
}
public enum RedirectType {
MOVED_PERMANENTLY,
FOUND,
SEE_OTHER,
TEMPORARY_REDIRECT
}
} |
There is a typical use-case for get/find/fetch API like below
where
null
can be returned from a route handler, some time ago the encoder was simply failing on this. Right now it returns justnull
as text. But it is still not a legal JSON response. The desired behavior is, typically, to return a404
response in this case.It is a bit boilerplate to add a null check in every handler like above, so, what I usually do in this situation, is just add a dead simple
after()
handler that does the null-check and throws 404.Would it be OK if I add a similar
after
handler to the project?The text was updated successfully, but these errors were encountered: