mu-server icon indicating copy to clipboard operation
mu-server copied to clipboard

JAX-RS service with class level Path("") annotation cannot handle requests.

Open SpinyOwl opened this issue 2 years ago • 4 comments

So any method with Path annotation will not be resolved as pattern matcher created from path annotation on class level will return false for any sequence.

SpinyOwl avatar May 30 '23 14:05 SpinyOwl

https://github.com/3redronin/mu-server/blob/master/src/main/java/io/muserver/rest/UriPattern.java#L175-L180

        // 4. If the resulting string ends with '/' then remove the final character.
        if (regex.length() > 0 && regex.lastIndexOf("/") == regex.length() - 1) {
            regex.delete(regex.length() - 1, regex.length());
        }

        // 5. Append '(/.*)?' to the result.
        regex.append("(/.*)?");

Maybe this should be replaced with just

        regex.append("(.*)?");

or with additional check if the regex is empty - then regex.append("(.*)?"); else the original logic.

SpinyOwl avatar May 31 '23 19:05 SpinyOwl

@danielflower any thoughts?

SpinyOwl avatar Jul 25 '23 12:07 SpinyOwl

I can't remember all the details around this, but in general if sufficient tests are added and they pass then I'd be fine. I'd be curious to know what the spec says that allows empty strings - maybe it doesn't cover this case, or maybe the code is not following the spec for this.

danielflower avatar Jul 25 '23 12:07 danielflower

As far as I understood from the documentation, @Path could contain empty string or /. One more thing is that it would be inconvenient to specify multiple root-level resources in several different classes.

Otherwise, instead of this:

@Path("/")
@Produces(MediaType.TEXT_PLAIN)
public class InfoResource {
  @Path("/health")
  @GET
  public String health() {
    return "OK";
  }

  @Path("/ready")
  @GET
  public String readiness() {
    return "OK";
  }
}

We would need to do something like this:

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class InfoResource {
  @Path("/health")
  @Produces(MediaType.TEXT_PLAIN)
  public static class HealthResource implements Resource {
    @GET
    public String health() {
      return "OK";
    }
  }

  @Path("/ready")
  @Produces(MediaType.TEXT_PLAIN)
  public static class ReadinessResource implements Resource {
    @GET
    public String readiness() {
      return "OK";
    }
  }
}

SpinyOwl avatar Jul 27 '23 09:07 SpinyOwl