title: Limiting the values of Query Params JAX-RS with CXF as implementation
body: <p>I have a use case where I need to limit the values that can be passed as the query param.</p>
  
  <pre><code>@Path("/foo")
  public interface Foo {
  
      @GET
      @Path("/details/id/{id}")
      void getFooDetails(@PathParam("id") String id, @QueryParam("sort") String sortDirection);
  }
  
  public class FooImpl {
      public void getFooDetails(String id, String sortDir) {
          //Implementation
      }
  }
  </code></pre>
  
  <p>In the above example, I want to restrict the value of query param <code>sort</code> that can be passed via the API to <code>ASC, DESC</code>. </p>
  
  <p>Is there any existing CXF annotation which I can use to restrict the values on a parameter? I haven't found any and so I tried the following solution.</p>
  
  <p><strong>My Approach:</strong></p>
  
  <pre><code>@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
  @Retention(RetentionPolicy.RUNTIME)
  @Inherited
  public @interface ValueSet {
  
      String[] allowedValues();
  }
  </code></pre>
  
  <p>The modified interface looks like this.</p>
  
  <pre><code>@Path("/foo")
  public interface Foo {
  
      @GET
      @PathParam("/details/id/{id}")
      void getFooDetails(@PathParam("id") String id, @QueryParam("sort") @ValueSet(allowedValues = {"ASC", "DESC"}) String sortDirection);
  }
  </code></pre>
  
  <p>I wrote a CXF Interceptor which intercepts the API invocation. I used reflection to get a handle on <code>FooImpl.getFooDetails</code> params. But the problem I faced is that the interceptor looks at FooImpl.getFooDetails method and doesn't find the annotations @QueryParam on the method params since @QueryParam is on the base method and the annotation is not inherited. </p>
  
  <p>Interceptor implementation:</p>
  
  <pre><code>@Provider
  public class ParamValidationInterceptor extends AbstractPhaseInterceptor&lt;Message&gt; {
  
      public ParamValidationInterceptor() {
          super(Phase.PRE_INVOKE);
          super.addBefore(someInterceptor);
      }
  
      @Override
      public void handleMessage(Message message) throws Fault {
  
          UriInfo uriInfo = new UriInfoImpl(message);
          MultivaluedMap&lt;String, String&gt; queryParams = uriInfo.getQueryParameters();
          Method methodToInvoke = (Method) message.get("org.apache.cxf.resource.method");
          Parameter[] parameters = methodToInvoke.getParameters();
          for (Parameter parameter : parameters) {
  
              if (parameter.isAnnotationPresent(ValueSet.class)) {
                  ValueSet valueSet = parameter.getAnnotation(ValueSet.class);
                  QueryParam queryParam = parameter.getAnnotation(QueryParam.class);
                  Object invokedVal = queryParams.get(queryParam.value());
  
                  String[] allowedValues = valueSet.allowedValues();
  
                  if (!Arrays.asList(allowedValues).contains(invokedVal)) {
                      throw new CustomException();
                  }
              }
          }
  
      }
  }
  </code></pre>
  
  <p>Can anyone suggest a way forward? It would be great if anyone can suggest an alternative approach.</p>
  
  <p>P.S: I am using CXF as an implementation for JAX-RS and spring is used as a container. </p>
  
  <p><strong>Update:</strong></p>
  
  <p>Like @Cássio Mazzochi Molin and @Andy McCright suggested, I will go with @Pattern annotation. But I am curious to know why the JAX-RS annotations are not inherited from the interface although the spec says they will be inherited.</p>