Skip to content

Add HttpStatus enum for status code #263

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@
/**
* The response status code to use.
*/
int statusCode() default 0;
HttpStatus statusCode() default HttpStatus.__not_set;
}
84 changes: 84 additions & 0 deletions http-api/src/main/java/io/avaje/http/api/HttpStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.avaje.http.api;

public enum HttpStatus {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk, most microframeworks provide their own HTTP status enum

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how would they use it on an avaje annotation?

Currently we use an int meaning folks need to know the http status codes which is maybe OK but in theory this helps them. Is there a better way?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk, I like using int

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, we can stick with int.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the thought of adding a java comment in the generated code [where the generated code sets the status] that translates the status code int into the reason description (for the purpose of helping the person reading the generated code who may not know the status code being used).

That way we use int, but at least the generated code might be more readable for devs reading the [generated] code later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good to me

CONTINUE_100(100),
SWITCHING_PROTOCOLS_101(101),
PROCESSING_102(102),

OK_200(200),
CREATED_201(201),
ACCEPTED_202(202),
NON_AUTHORITATIVE_INFORMATION_203(203),

NO_CONTENT_204(204),
RESET_CONTENT_205(205),
PARTIAL_CONTENT_206(206),
MULTI_STATUS_207(207),
ALREADY_REPORTED_208(208),
IM_USED_226(226),

MULTIPLE_CHOICES_300(300),
MOVED_PERMANENTLY_301(301),
FOUND_302(302),
SEE_OTHER_303(303),
NOT_MODIFIED_304(304),
USE_PROXY_305(305),
TEMPORARY_REDIRECT_307(307),
PERMANENT_REDIRECT_308(308),

BAD_REQUEST_400(400),
UNAUTHORIZED_401(401),
PAYMENT_REQUIRED_402(402),
FORBIDDEN_403(403),
NOT_FOUND_404(404),
METHOD_NOT_ALLOWED_405(405),
NOT_ACCEPTABLE_406(406),
PROXY_AUTHENTICATION_REQUIRED_407(407),
REQUEST_TIMEOUT_408(408),
CONFLICT_409(409),
GONE_410(410),
LENGTH_REQUIRED_411(411),
PRECONDITION_FAILED_412(412),
REQUEST_ENTITY_TOO_LARGE_413(413),
URI_TOO_LONG_414(414),
UNSUPPORTED_MEDIA_TYPE_415(415),
REQUESTED_RANGE_NOT_SATISFIABLE_416(416),
EXPECTATION_FAILED_417(417),
I_AM_A_TEAPOT_418(418),
MISDIRECTED_REQUEST_421(421),
UNPROCESSABLE_ENTITY_422(422),
LOCKED_423(423),
FAILED_DEPENDENCY_424(424),
TOO_EARLY_425(425),
UPGRADE_REQUIRED_426(426),
PRECONDITION_REQUIRED_428(428),
TOO_MANY_REQUESTS_429(429),
REQUEST_HEADER_FIELDS_TOO_LARGE_431(431),
UNAVAILABLE_FOR_LEGAL_REASONS_451(451),

INTERNAL_SERVER_ERROR_500(500),
NOT_IMPLEMENTED_501(501),
BAD_GATEWAY_502(502),
SERVICE_UNAVAILABLE_503(503),
GATEWAY_TIMEOUT_504(504),
HTTP_VERSION_NOT_SUPPORTED_505(505),
VARIANT_ALSO_NEGOTIATES_506(506),
INSUFFICIENT_STORAGE(507),
LOOP_DETECTED(508),
BANDWIDTH_LIMIT_EXCEEDED_509(509),
NOT_EXTENDED_510(510),
NETWORK_AUTHENTICATION_REQUIRED(511),

__not_set(0);

private final int code;

HttpStatus(int code) {
this.code = code;
}

public int code() {
return code;
}

}
2 changes: 1 addition & 1 deletion http-api/src/main/java/io/avaje/http/api/Produces.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@
* PATCH(200, void methods 204) <br>
* DELETE(200, void methods 204)
*/
int statusCode() default 0;
HttpStatus statusCode() default HttpStatus.__not_set;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package io.avaje.http.generator.core;

public enum CopyHttpStatus {
CONTINUE_100(100),
SWITCHING_PROTOCOLS_101(101),
PROCESSING_102(102),

OK_200(200),
CREATED_201(201),
ACCEPTED_202(202),
NON_AUTHORITATIVE_INFORMATION_203(203),

NO_CONTENT_204(204),
RESET_CONTENT_205(205),
PARTIAL_CONTENT_206(206),
MULTI_STATUS_207(207),
ALREADY_REPORTED_208(208),
IM_USED_226(226),

MULTIPLE_CHOICES_300(300),
MOVED_PERMANENTLY_301(301),
FOUND_302(302),
SEE_OTHER_303(303),
NOT_MODIFIED_304(304),
USE_PROXY_305(305),
TEMPORARY_REDIRECT_307(307),
PERMANENT_REDIRECT_308(308),

BAD_REQUEST_400(400),
UNAUTHORIZED_401(401),
PAYMENT_REQUIRED_402(402),
FORBIDDEN_403(403),
NOT_FOUND_404(404),
METHOD_NOT_ALLOWED_405(405),
NOT_ACCEPTABLE_406(406),
PROXY_AUTHENTICATION_REQUIRED_407(407),
REQUEST_TIMEOUT_408(408),
CONFLICT_409(409),
GONE_410(410),
LENGTH_REQUIRED_411(411),
PRECONDITION_FAILED_412(412),
REQUEST_ENTITY_TOO_LARGE_413(413),
URI_TOO_LONG_414(414),
UNSUPPORTED_MEDIA_TYPE_415(415),
REQUESTED_RANGE_NOT_SATISFIABLE_416(416),
EXPECTATION_FAILED_417(417),
I_AM_A_TEAPOT_418(418),
MISDIRECTED_REQUEST_421(421),
UNPROCESSABLE_ENTITY_422(422),
LOCKED_423(423),
FAILED_DEPENDENCY_424(424),
TOO_EARLY_425(425),
UPGRADE_REQUIRED_426(426),
PRECONDITION_REQUIRED_428(428),
TOO_MANY_REQUESTS_429(429),
REQUEST_HEADER_FIELDS_TOO_LARGE_431(431),
UNAVAILABLE_FOR_LEGAL_REASONS_451(451),

INTERNAL_SERVER_ERROR_500(500),
NOT_IMPLEMENTED_501(501),
BAD_GATEWAY_502(502),
SERVICE_UNAVAILABLE_503(503),
GATEWAY_TIMEOUT_504(504),
HTTP_VERSION_NOT_SUPPORTED_505(505),
VARIANT_ALSO_NEGOTIATES_506(506),
INSUFFICIENT_STORAGE(507),
LOOP_DETECTED(508),
BANDWIDTH_LIMIT_EXCEEDED_509(509),
NOT_EXTENDED_510(510),
NETWORK_AUTHENTICATION_REQUIRED(511),

__not_set(0);

private final int code;

CopyHttpStatus(int code) {
this.code = code;
}

public int code() {
return code;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class MethodReader {
private final Optional<RequestTimeoutPrism> timeout;

private WebMethod webMethod;
private int statusCode;
private CopyHttpStatus statusCode = CopyHttpStatus.__not_set;
private String webMethodPath;
private boolean formMarker;
private final boolean instrumentContext;
Expand Down Expand Up @@ -169,7 +169,7 @@ private void initSetWebMethod(WebMethod webMethod, String value) {

private void initSetWebMethod(WebMethod webMethod, ExceptionHandlerPrism exceptionPrism) {
this.webMethod = webMethod;
this.statusCode = exceptionPrism.statusCode();
this.statusCode = CopyHttpStatus.valueOf(exceptionPrism.statusCode());
var exType = exceptionPrism.value().toString();
if ("io.avaje.http.api.DefaultException".equals(exType)) {
exType =
Expand Down Expand Up @@ -352,7 +352,11 @@ public boolean isVoid() {
}

public boolean hasProducesStatus() {
return producesAnnotation.map(ProducesPrism::statusCode).filter(s -> s > 0).isPresent();
return producesAnnotation
.map(ProducesPrism::statusCode)
.map(CopyHttpStatus::valueOf)
.filter(s -> s.code() > 0)
.isPresent();
}

public String produces() {
Expand All @@ -379,12 +383,14 @@ public TypeMirror returnType() {
}

public int statusCode() {
if (statusCode > 0) {
if (statusCode.code() > 0) {
// using explicit status code
return statusCode;
return statusCode.code();
}
return producesAnnotation
.map(ProducesPrism::statusCode)
.map(CopyHttpStatus::valueOf)
.map(CopyHttpStatus::code)
.filter(s -> s > 0)
.orElseGet(() -> webMethod.statusCode(isVoid));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@

import java.util.List;

import io.avaje.http.api.Controller;
import io.avaje.http.api.Get;
import io.avaje.http.api.MediaType;
import io.avaje.http.api.OpenAPIResponse;
import io.avaje.http.api.OpenAPIResponses;
import io.avaje.http.api.Path;
import io.avaje.http.api.Post;
import io.avaje.http.api.Produces;
import io.avaje.http.api.Put;
import io.avaje.http.api.*;
import io.javalin.http.Context;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
Expand Down Expand Up @@ -84,7 +76,7 @@ Person testPostList(List<Person> m) {
}

@Put("/put")
@Produces(value = MediaType.TEXT_PLAIN, statusCode = 203)
@Produces(value = MediaType.TEXT_PLAIN, statusCode = HttpStatus.NON_AUTHORITATIVE_INFORMATION_203)
@OpenAPIResponse(responseCode = "204", type = String.class)
String testDefaultStatus(Context ctx) {
if (ctx.contentType().equals(MediaType.APPLICATION_PDF)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.avaje.http.api.Controller;
import io.avaje.http.api.ExceptionHandler;
import io.avaje.http.api.HttpStatus;
import io.helidon.nima.webserver.http.ServerRequest;
import io.helidon.nima.webserver.http.ServerResponse;

Expand All @@ -13,7 +14,7 @@
@Controller
final class ErrorController {

@ExceptionHandler(statusCode = 407)
@ExceptionHandler(statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407)
Map<String, Object> runEx(RuntimeException ex, ServerRequest req, ServerResponse res) {
return Map.of("err", "" + ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ String strBody(@BodyString String body) {
return body;
}

@Produces(statusCode = 202)
@Produces(statusCode = HttpStatus.ACCEPTED_202)
@Post("/blah")
Map<String, Object> strBody2() {
var map = new LinkedHashMap<String, Object>();
Expand All @@ -83,7 +83,7 @@ String exception(IllegalArgumentException ex) {
return "Err: " + ex;
}

@Produces(statusCode = 501)
@Produces(statusCode = HttpStatus.NOT_IMPLEMENTED_501)
@ExceptionHandler
Person exceptionCtx(Exception ex, ServerRequest req, ServerResponse res) {
res.header("X-Foo", "WasHere");
Expand Down