Spring BootとJPAを使用した2-TIL(1)
16982 ワード
[参考講座]実戦!Spring BootとJPAによる2-APIの開発とパフォーマンスの最適化
問題 エンティティは、プレゼンテーションレイヤの論理を追加します. エンティティは、API検証のための論理(@NotEmptyなど) を含む実務では、会員エンティティのために作成されるAPIは多様であり、1つのエンティティに各APIのすべての要求要件を含めることは困難である. エンティティが変更されると、API仕様は に変更されます.
結論 API要求の仕様に従って、個別のDTOパラメータが受け入れられる.
要求値として、メンバーエンティティではなく個別のDTOが受信されます. CreateMemberRequestをメンバーエンティティではなくRequest Bodyにマッピングします. エンティティとプレゼンテーションレイヤの論理を分離できます. エンティティは、API仕様から明確に分離されることができる. エンティティが変更された場合、API仕様は変更されません. エンティティをAPI仕様に露出しないでください.
会員照会V 1:エンティティを応答値の外に直接暴露する問題 エンティティは、プレゼンテーションレイヤの論理を追加します. デフォルトでは、エンティティのすべての値が露出します. 応答specに合わせるために論理を追加した.(@JosonIgnore等) の実践では、同じエンティティのAPIは、用途によって異なり、1つのエンティティに各APIに対するプレゼンテーション応答ロジックを含めることは困難である. エンティティが変更されると、API仕様が変更されます. さらにローカル集合を直接返却すると,今後のAPI規格の変更は困難である.(個別のResultクラスを作成して解決) 結論 API応答specに従って個別のDTOが返される. 会員照会V 2:エンティティではなく独立したDTOを応答値として使用エンティティをDTOに戻します. エンティティが変更されても、API仕様は変更されません. Resultクラスのローカルセットを追加して、将来必要なフィールドを追加します.
💡 API開発基盤
会員登録API
@RestController
@RequiredArgsConstructor
public class MemberApiController {
private final MemberService memberService;
@PostMapping("/api/v1/members")
public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) {
Long id = memberService.join(member);
return new CreateMemberResponse(id);
}
@Data
static class CreateMemberRequest {
@NotEmpty
private String name;
}
@Data
static class CreateMemberResponse {
private Long id;
public CreateMemberResponse(Long id) {
this.id = id;
}
}
}
V 1エンティティをRequest Bodyに直接マッピング
DTOをV 2エンティティではなくRequest Bodyにマッピング
要求値として、メンバーエンティティではなく個別のDTOが受信されます.
@PostMapping("/api/v2/members")
public CreateMemberResponse saveMemberV2(@RequestBody @Valid CreateMemberRequest request) {
Member member = new Member();
member.setName(request.getName());
Long id = memberService.join(member);
return new CreateMemberResponse(id);
}
#会員APIの変更
@PutMapping("/api/v2/members/{id}")
public UpdateMemberResponse updateMemberV2(
@PathVariable("id") Long id,
@RequestBody @Valid UpdateMemberRequest request) {
memberService.update(id, request.getName());
Member findMember = memberService.findOne(id);
return new UpdateMemberResponse(findMember.getId(), findMember.getName());
}
@Data
static class UpdateMemberRequest {
private String name;
}
@Data
@AllArgsConstructor
static class UpdateMemberResponse {
private Long id;
private String name;
}
MemberService @Transactional
public void update(Long id, String name) {
Member member = memberRepository.findOne(id);
member.setName(name);
}
▼▼▼会員照会API
会員照会V 1:エンティティを応答値の外に直接暴露する
public class MemberApiController {
private final MemberService memberService;
@GetMapping("/api/v1/members")
public List<Member> membersV1() {
return memberService.findMembers();
}
}
@GetMapping("/api/v2/members")
public Result membersV2() {
List<Member> findMembers = memberService.findMembers();
List<MemberDto> collect = findMembers.stream()
.map(m -> new MemberDto(m.getName()))
.collect(Collectors.toList());
return new Result(collect.size(), collect);
}
@Data
@AllArgsConstructor
static class Result<T> {
private int count;
private T data;
}
@Data
@AllArgsConstructor
static class MemberDto {
private String name;
}
Reference
この問題について(Spring BootとJPAを使用した2-TIL(1)), 我々は、より多くの情報をここで見つけました https://velog.io/@yulhee741/Spring-Boot와-JPA-활용2-TIL1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol