DTO 구성


요청 DTO - 글 작성 요청 DTO 구성

요청 DTO가 글 작성 시 필요한 정보들을 담을 수 있도록 구성하기 위해, 많은 고민을 해야했다.

내가 원하는 JSON data 타입은 다음과 같다.

{
  "title" : "d",
  "recruitType" : "type",
  "contact" : "contact",
  "recruitIntroduction" : "intro",
  
  "fieldsRequests" : [
    {
      "fieldsName" : "name1",
      "recruitCount" : 1,
      "totalAbility" : 6,
      
      "techStackRequests" : [
        {
          "stackName" : "name1"
        },
        {
          "stackName" : "name2"
        }
      ]
    },
    {
      "fieldsName" : "name2",
      "recruitCount" : 3,
      "totalAbility" : 4,
      
      "techStackRequests" : [
        {
          "stackName" : "name3"
        },
        {
          "stackName" : "name4"
        }
      ]
    }
  ]
}

이를 구현하기 위해 총 3 개의 요청 DTO를 작성하였다.

// 1. 글 작성 관련 DTO
// Class name : CreatePostRequest

@Getter
public class CreatePostRequest {
    @NotBlank
    private String title;

    @NotBlank
    private String recruitType;

    @NotBlank
    private String contact;

    @NotBlank
    private String recruitIntroduction;

    @NotBlank
    private List<CreateFieldsRequest> fieldsRequests;

}

// 2. 모집 분야 관련 DTO
// Class name : CreateFieldsRequest

@Getter
public class CreateFieldsRequest {
    @NotBlank
    private String fieldsName;

    @NotBlank
    private Integer recruitCount;

    @NotBlank
    private Integer totalAbility;

    @NotBlank
    private List<CreatedTechStackRequest> techStackRequests;
}

// 3. 기술 스택 관련 DTO
// Class name : CreatedTechStackRequest

@Getter
public class CreatedTechStackRequest {

    @NotBlank
    private String stackName;
}

1차적으로 위와 같이 구성하고, Service단에서 정보를 처리하려고 헀다.

public PostResponse createPost(CreatePostRequest postDto) {
    String recruitType = postDto.getRecruitType();

    Post post = Post.builder()
            .title(postDto.getTitle())
            .recruitType(recruitType.equals("스터디") ?STUDY:PROJECT)
            .contact(postDto.getContact())
            .recruitIntroduction(postDto.getRecruitIntroduction())
            .build();

    List<Fields> fields = postDto.getFieldsRequests().stream()
            .map(fieldsDto -> Fields.builder()
                    .post(post)
                    .fieldsName(fieldsDto.getFieldsName())
                    .recruitCount(fieldsDto.getRecruitCount())
                    .totalAbility(fieldsDto.getTotalAbility())
                    .build())
            .collect(Collectors.toList());

    //techStackDto랑 Field랑 어떻게 매칭하지..

    return null;
}

그런데, 아무리 생각해도 위와 같은 구조는 Field DTO를 Fields 객체로 변환함과 동시에, techStack DTO를 techStack 객체로 변환하면서, 동시에 기술 스택에 해당하는 Fields랑 매칭하기가 너무 어려웠다. (사실은 아예 어떻게 해야할지를 모르겠다.)

첫번째 시도 - Map으로 관리해보기

@NotBlank
private final Map<CreateFieldsRequest, List<CreatedTechStackRequest>> fieldsAndTechStack;

FieldDto : List<TechStackDto>의 형태로 관리해보고자 했다.

그에 따라 서비스단은 아래와 같이 구성했다.

public PostResponse createPost(CreatePostRequest postDto) {
    String recruitType = postDto.getRecruitType();

    Post post = Post.builder()
            .title(postDto.getTitle())
            .recruitType(recruitType.equals("스터디") ?STUDY:PROJECT)
            .contact(postDto.getContact())
            .recruitIntroduction(postDto.getRecruitIntroduction())
            .build();

    //techStackDto랑 Field랑 어떻게 매칭하지..
    //동시에 다른 DTO로 받아오지 않는 이상 동시 처리가 불가능할 것 같다. List -> Map으로 바꿔보자
    Map<CreateFieldsRequest, List<CreatedTechStackRequest>> fieldsAndTechStack = postDto.getFieldsAndTechStack();
    for (CreateFieldsRequest fieldDto : fieldsAndTechStack.keySet()) {
        Fields fields = Fields.builder()
                .post(post)
                .fieldsName(fieldDto.getFieldsName())
                .recruitCount(fieldDto.getRecruitCount())
                .totalAbility(fieldDto.getTotalAbility())
                .build();

        fieldsAndTechStack.get(fieldDto)
                .forEach(techStackDto -> TechStack
                        .builder()
                        .stackName(techStackDto.getStackName())
                        .fields(fields)
                        .build());
    }

    postRepository.save(post);

    return new PostResponse(post);
}

그러고나서 Test를 돌렸는데, 415 ERROR가 발생했다.

415 Unsupported Media Type - HTTP | MDN