データベースで CRUD 操作を実行するための REST API を構築しています。私の暫定的なスタックは、Jersey、Spring、Spring Data、JPA、および Hibernate です。また、jersey-spring を使用してリソース クラスのインスタンスを提供し、Spring が自動配線できるようにしています。
API は、付随する JPA エンティティと Spring Data リポジトリに支えられた DAO を使用して、多数のテーブルで CRUD 操作をサポートします。DAO インターフェイスと関連する DTO のファミリは、次のようになります。
public interface CrudService<T extends PersistedObject> { /* ... */ }
public interface PersonService extends CrudService<Person> { /* ... */ }
public class PersistedObject { /* ... */ }
public class Person extends PersistedObject { /* ... */ }
以下は、JAX-RS リソース クラスの簡略化されたバージョンです。
@Component
@Path("/people")
public class PersonResource {
@Autowired
private PersonService personService;
@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Person get(@PathParam("id") String id) {
return personService.findOne(Long.valueOf(id));
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response post(Person person) {
personService.save(person);
return Response.created().build();
}
}
問題は、残りの数十のリソース クラスがほとんど同じに見えることです。唯一の違いは、異なる PersistedObject サブクラスとそれに対応する DAO で動作することです。おそらく多形性とDAOの巧妙な注入によって、すべてのエンティティタイプでCRUD操作をサポートできる1つのリソースクラスを持つことで、DRYを維持したいと思います。次のようになります。
@Component
@Path("/{resourceType}")
public class CrudResource {
@Autowired
private CrudService crudService;
@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public PersistedObject get(@PathParam("id") String id) {
return crudService.findOne(Long.valueOf(id));
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response post(PersistedObject entity) {
crudService.save(entity);
return Response.created().build();
}
}
私が解決する必要がある問題:
- リソース メソッドが PersistedObject を受け入れて返す場合、Jersey/Jackson はシリアル化/逆シリアル化の方法をどのように知るのでしょうか? path パラメーターの
resourceType
変数は、ユーザーが要求している具体的な型を示していますが、これをうまく利用する方法がわかりません。 - Spring がリソース クラス インスタンスを提供するとき、注入する DAO をどのように知るのでしょうか?
全体として、私が正しい道を進んでいるかどうかはわかりません。これを一般的な方法で実装することは可能ですか?