API プロジェクトのアーキテクチャに使用できるオプションを見つけようとしています。
JAX-RS バージョン 1.0 を使用して API を作成したいと考えています。この API は、大きくて古い複雑なアプリケーションからリモート EJB (EJB 3.0) を使用します。私はJava 6を使用しています。
これまでのところ、私はこれを行うことができ、動作します。しかし、私は解決策に満足していません。私のパッケージの処分を参照してください。私の懸念は、コードの後に説明されています。
/api/
/com.organization.api.v1.rs -> Rest Services with the JAX-RS annotations
/com.organization.api.v1.services -> Service classes used by Rest Services. Basically, they only have the logic to transform the DTOs objects from Remote EJBs in JSON. This is separated by API version, because the JSON can be different in each version.
/com.organization.api.v1.vo -> View Objects returned by the Rest Services. They will be transformed in JSON using Gson.
/com.organization.api.services -> Service classes used by versioned Services.
Here we have the lookup for Remote EJBs and some API logic, like validations. This services can be used by any versioned of each Service.
の例com.organization.api.v1.rs.UserV1RS
:
@Path("/v1/user/")
public class UserV1RS {
@GET
public UserV1VO getUsername() {
UserV1VO userVO = ServiceLocator.get(UserV1Service.class).getUsername();
return userVO;
}
}
の例com.organization.api.v1.services.UserV1Service
:
public class UserV1Service extends UserService {
public UserV1VO getUsername() {
UserDTO userDTO = getUserName(); // method from UserService
return new UserV1VO(userDTO.getName);
}
}
の例com.organization.api.services.UserService
:
public class UserService {
public UserDTO getUsername() {
UserDTO userDTO = RemoteEJBLocator.lookup(UserRemote.JNDI_REMOTE_NAME).getUser();
return userDTO;
}
}
私のプロジェクトのいくつかの要件:
- API には、v1、v2 などのバージョンがあります。
- バージョン管理された同じ Service の異なる API バージョンは、コードを共有できます:
UserV1Service
およびUserV2Service
を使用しUserService
ます。 - 異なるバージョンのサービスの異なる API バージョンは、コードを共有できます:
UserV1Service
およびOrderV2Service
を使用しAnotherService
ます。 - 各バージョンには独自のビュー オブジェクトがあります (
UserV1VO
ではありませんUserVO
)。
上記のコードについて私を悩ませているのは:
- この
ServiceLocator
クラスは私にとって良いアプローチではありません。このクラスは古いライブラリのレガシー コードを使用しており、このクラスがどのように機能するかについて多くの質問があります。の使用方法ServiceLocator
は私にとっても非常に奇妙であり、この戦略は単体テスト用のサービスをモックするのには適していません 。新しい ServiceLocator を作成するか、依存性注入戦略 (または別のより良いアプローチ) を使用したいと考えています。 - この
UserService
クラスは、 などの別の「外部」サービスによって使用されることを意図していませんOrderService
。のみですUserVxService
。しかし、将来的には、OrderService
いくつかのコードを使用したいと思うかもしれませんUserService
... - 最後の問題を無視したとしても、 を使用すると、コード内で
ServiceLocator
多くのことを行う必要があります。lookups
循環的な依存関係 (serviceOne をルックアップする serviceTwo が serviceThree をルックアップする serviceOne をルックアップする) が作成される可能性は非常に高くなります。 - このアプローチでは、 のような VO を
UserV1VO
バージョン管理されていないサービス (com.organization.api.services
) で使用できますが、これは実現できません。優れたアーキテクチャは、許可されていないものを許可しません。これを避けるために、新しいプロジェクトを作成してそこにapi-services
置くという考えがあります。com.organization.api.services
これは良い解決策ですか?
それで... アイデア?