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

Request headers management #277

Merged
merged 3 commits into from Sep 9, 2017

Conversation

Projects
None yet
2 participants
@fcamblor
Contributor

fcamblor commented Sep 1, 2017

PR to fix first part of #101 concerning request headers management

Those request headers will be handled exactly the same (such as Optional handling and Jackson deserialization) as PATH or QUERY parameters, following what has been prepared in PR #177 (better query parameters)

2 different forms of definig request header will be available :

  • The "short" form, using the all new @HeaderParam annotation :
  • The "long" form, using existing @Param annotation

Both forms can be shown in samplest's ParametersResource :

    @GET("/params/headers")
    public String headerParams(@Param(value = "X-A", kind = Param.Kind.HEADER) String a, @HeaderParam("X-B") Optional<DateTime> b, @HeaderParam Optional<String> Date) {
        return "a=" + a + " b=" + b.orNull() + " date=" + String.valueOf(Date.orNull());
    }

which will generate following StdEntityRoute code :

        new StdEntityRoute<Void, java.lang.String>("default#ParametersResource#headerParams",
                readerRegistry.<Void>build(Void.class, Optional.<String>absent()),
                writerRegistry.<java.lang.String>build(java.lang.String.class, Optional.<String>absent()),
                Endpoint.of("GET", "/params/headers"),
                HttpStatus.OK, RestxLogLevel.DEFAULT, pf,
                paramMapperRegistry, new ParamDef[]{
                    ParamDef.of(new TypeReference<java.lang.String>(){}, "X-A"),
                    ParamDef.of(new TypeReference<org.joda.time.DateTime>(){}, "X-B"),
                    ParamDef.of(new TypeReference<java.lang.String>(){}, "Date")
                }) {
            @Override
            protected Optional<java.lang.String> doRoute(RestxRequest request, RestxRequestMatch match, Void body) throws IOException {
                securityManager.check(request, match, open());
                try {
                    return Optional.of(resource.headerParams(
                        /* [HEADER] X-A */ checkValid(validator, checkNotNull(mapQueryObjectFromRequest(java.lang.String.class, "X-A", request, match, EndpointParameterKind.HEADER), "HEADER param <a> is required")),
                        /* [HEADER] X-B */ Optional.fromNullable(checkValid(validator, mapQueryObjectFromRequest(org.joda.time.DateTime.class, "X-B", request, match, EndpointParameterKind.HEADER))),
                        /* [HEADER] Date */ Optional.fromNullable(checkValid(validator, mapQueryObjectFromRequest(java.lang.String.class, "Date", request, match, EndpointParameterKind.HEADER)))
                    ));
                } catch(RuntimeException e) { throw e; }
                  catch(Exception e) { throw new WrappedCheckedException(e); }
            }

            @Override
            protected void describeOperation(OperationDescription operation) {
                super.describeOperation(operation);
                OperationParameterDescription a = new OperationParameterDescription();
                a.name = "X-A";
                a.paramType = OperationParameterDescription.ParamType.header;
                a.dataType = "string";
                a.schemaKey = "";
                a.required = true;
                operation.parameters.add(a);

                OperationParameterDescription b = new OperationParameterDescription();
                b.name = "X-B";
                b.paramType = OperationParameterDescription.ParamType.header;
                b.dataType = "Date";
                b.schemaKey = "org.joda.time.DateTime";
                b.required = false;
                operation.parameters.add(b);

                OperationParameterDescription Date = new OperationParameterDescription();
                Date.name = "Date";
                Date.paramType = OperationParameterDescription.ParamType.header;
                Date.dataType = "string";
                Date.schemaKey = "";
                Date.required = false;
                operation.parameters.add(Date);


                operation.responseClass = "string";
                operation.inEntitySchemaKey = "";
                operation.outEntitySchemaKey = "";
                operation.sourceLocation = "samplest.core.ParametersResource#headerParams(java.lang.String,com.google.common.base.Optional<org.joda.time.DateTime>,com.google.common.base.Optional<java.lang.String>)";
            }
        },
@xhanin

This comment has been minimized.

Contributor

xhanin commented Sep 2, 2017

Great job!

I'm just wondering about the naming, wouldn't Kind.HEADER be enough? We currently have PATH, QUERY, ... and HEADER for a Param.Kind seems clear enough |MO.

Same for the annotation, it's a good idea, we could also introduce similar annotations for path, query and context annotations, in which case I'm wondering what we should use. Maybe using names similar to jaxrs would be easier to understand: @PathParam, @QueryParam, @ContextParam and therefore for request header @HeaderParam. What do you think?

@fcamblor

This comment has been minimized.

Contributor

fcamblor commented Sep 3, 2017

OK, renamed REQUEST_HEADER to HEADER + Introduced @PathParam, @QueryParam and @ContextParam annotation aliases

updated PR description accordingly

@fcamblor fcamblor merged commit 4caf460 into restx:master Sep 9, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment