JAX-RSを使用してRESTfulAPIを開発しています。私のAPIの簡略版は次のとおりです。
GET /appapi/v1.0/users
POST /appapi/v1.1/users
... ... and so on
ご覧のとおり、パターンは次のとおり{api_name}/v{major_version}.{minor_version}/{rest_of_the_path}
です。
追加の要件があります:
バージョンが指定されていない場合は、デフォルトで最新バージョンを使用する必要があります。
GET /appapi/users
と同等である必要がありますGET /appapi/v1.1/users
(1.1がユーザーの最新バージョンであると想定)。
これが、JAXRSを使用してこれを実装した方法です。
@Path("/appapi")
public class AppApiRootResource {
@Path("/{version: [v]\\d+[[.]\\d+]?}/")
public AppApiSubResource getVersionedSubResource
(@PathParam("version") String version){
System.out.println("Version: "+version);
String versionString = version.substring(1); //Discard the leading 'v'
String majorVersion = "";
String minorVersion = "0";
if(versionString.contains(".")){
String [] splits = versionString.split(".");
majorVersion = splits[0];
minorVersion = splits[1];
} else {
majorVersion = versionString;
}
return SubResourceFactory.getSubResource(majorVersion, minorVersion);
}
@Path("/{^([v]\\d+[[.]\\d+]?)}/") //Is This Correct??
public AppApiSubResource getDefaultApiResource(){
/*
* Need help defining the regular expression here
* so that this is used for anything that doesn't match
* the "version" regexp above
*/
System.out.println("API version not specified; Using default version");
return SubResourceFactory.getLatestVersionSubResource();
}
}
私のサブリソースクラスは次のように定義されています。APIの複数のバージョンを処理するために、このクラスのサブクラスがあります。の実装はSubResourceFactory
、この説明の目的には関係ありません。AppApiSubResource
のインスタンスまたはそのサブクラスを返すだけです
public class AppApiSubResource {
/**
* Create a new user
*/
@POST
@Path("users")
@Consumes(MediaType.APPLICATION_XML)
public Response createUser(String newUser, @Context UriInfo uriInfo) {
URI uri = uriInfo.getAbsolutePathBuilder().path("10")).build();
return Response.created(uri).build();
}
/**
* Get a user
*/
@GET
@Path("users/{id}")
@Produces(MediaType.APPLICATION_XML)
public Response getUser(@PathParam("id") String userId
) {
return Response.ok().entity("<user></user>").build();
}
}
問題文:
- コメントアウトする
getDefaultApiResource()
と、APIにバージョン指定子がある場合、期待どおりに機能します。ただし、コメントgetDefaultApiResource()
を解除すると、リクエストにv1.0が含まれているかどうかに関係なく、常に呼び出されます。- また、コメントを外すと、 (つまり、バージョン指定子なしで)
getDefaultApiResource()
実行すると404が返されます。GET /appapi/users
しかし、私が使用すればGET /appapi/v1.0/users
(つまり、バージョン指定子を使用して)問題なく動作します
では、リクエストにバージョン指定子がないときにメソッドが呼び出されるように、サブリソースロケーターパス/正規表現を設定するにはどうすればよいですか?
Restletフレームワークを使用していますが、この質問は実装に依存しません。