Skip to content

Commit

Permalink
merge(GroupRetrieveAPI) : 그룹 조회 API 구현
Browse files Browse the repository at this point in the history
[✨ feat] 그룹 조회 API 구현
  • Loading branch information
jsoonworld authored Feb 16, 2025
2 parents 6898eb9 + 0703f83 commit b22e4d7
Show file tree
Hide file tree
Showing 20 changed files with 625 additions and 43 deletions.
17 changes: 13 additions & 4 deletions src/main/java/org/noostak/group/api/GroupController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import org.noostak.group.application.GroupService;
import org.noostak.group.dto.request.GroupCreateRequest;
import org.noostak.group.dto.response.GroupCreateResponse;
import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

import static org.noostak.group.common.success.GroupSuccessCode.GROUP_CREATED;
import static org.noostak.group.common.success.GroupSuccessCode.GROUP_RETRIEVED;

@RestController
@RequestMapping("/api/v1/groups")
Expand All @@ -32,4 +31,14 @@ public ResponseEntity<SuccessResponse<GroupCreateResponse>> createGroup(
GroupCreateResponse response = groupService.createGroup(memberId, request);
return ResponseEntity.ok((SuccessResponse.of(GROUP_CREATED, response)));
}

@GetMapping
public ResponseEntity<SuccessResponse<GroupsRetrieveResponse>> getGroups(
// @AuthenticationPrincipal Long memberId
) {
// TODO: AuthenticationPrincipal
Long memberId = 1L;
GroupsRetrieveResponse groups = groupService.findGroups(memberId);
return ResponseEntity.ok(SuccessResponse.of(GROUP_RETRIEVED, groups));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.noostak.group.application;

import org.noostak.group.dto.response.GroupsRetrieveResponse;

public interface GroupRetrieveService {
GroupsRetrieveResponse findGroups(Long memberId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.noostak.group.application;

import lombok.RequiredArgsConstructor;
import org.noostak.group.common.exception.GroupErrorCode;
import org.noostak.group.common.exception.GroupException;
import org.noostak.group.domain.Groups;
import org.noostak.group.dto.response.GroupInternalRetrieveResponse;
import org.noostak.group.dto.response.GroupRetrieveResponse;
import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.noostak.infra.S3Service;
import org.noostak.membergroup.domain.MemberGroup;
import org.noostak.membergroup.domain.MemberGroupRepository;
import org.noostak.membergroup.domain.MemberGroups;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class GroupRetrieveServiceImpl implements GroupRetrieveService {

private final MemberGroupRepository memberGroupRepository;
private final S3Service s3Service;

@Override
public GroupsRetrieveResponse findGroups(Long memberId) {
MemberGroups memberGroups = getMemberGroups(memberId);
Groups groups = convertToGroups(memberGroups);
return convertToResponse(groups);
}

private MemberGroups getMemberGroups(Long memberId) {
List<MemberGroup> foundMemberGroups = memberGroupRepository.findByMemberId(memberId);
MemberGroups memberGroups = MemberGroups.of(foundMemberGroups);

if (memberGroups.isEmpty()) {
throw new GroupException(GroupErrorCode.GROUP_NOT_FOUND);
}

return memberGroups;
}

private Groups convertToGroups(MemberGroups memberGroups) {
return Groups.of(memberGroups.toGroups());
}

private GroupsRetrieveResponse convertToResponse(Groups groups) {
List<GroupInternalRetrieveResponse> internalResponses = groups.getGroups().stream()
.map(group -> GroupInternalRetrieveResponse.of(group, s3Service.getImageUrl(group.getKey().value())))
.toList();

List<GroupRetrieveResponse> groupResponses = internalResponses.stream()
.map(internal -> GroupRetrieveResponse.of(internal.group(), internal.groupProfileImageUrl()))
.toList();

return GroupsRetrieveResponse.of(groupResponses);
}
}
6 changes: 6 additions & 0 deletions src/main/java/org/noostak/group/application/GroupService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.noostak.group.dto.request.GroupCreateRequest;
import org.noostak.group.dto.response.GroupCreateInternalResponse;
import org.noostak.group.dto.response.GroupCreateResponse;
import org.noostak.group.dto.response.GroupsRetrieveResponse;
import org.springframework.stereotype.Service;

import java.io.IOException;
Expand All @@ -13,9 +14,14 @@
public class GroupService {

private final GroupCreateService groupCreateService;
private final GroupRetrieveService groupRetrieveService;

public GroupCreateResponse createGroup(Long memberId, GroupCreateRequest request) throws IOException {
GroupCreateInternalResponse response = groupCreateService.createGroup(memberId, request);
return GroupCreateResponse.of(response.group(), response.groupProfileImageUrl());
}

public GroupsRetrieveResponse findGroups(Long memberId) {
return groupRetrieveService.findGroups(memberId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public enum GroupErrorCode implements ErrorCode {
GROUP_CREATION_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "그룹 생성에 실패했습니다."),
GROUP_PROFILE_IMAGE_DELETE_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "그룹 프로필 이미지 삭제에 실패했습니다."),

GROUP_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹을 찾을 수 없습니다."),
GROUP_MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹 멤버를 찾을 수 없습니다."),
;

public static final String PREFIX = "[GROUP ERROR] ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
@AllArgsConstructor
public enum GroupSuccessCode implements SuccessCode {
GROUP_CREATED(HttpStatus.CREATED, "그룹이 성공적으로 생성되었습니다."),

GROUP_RETRIEVED(HttpStatus.OK, "그룹이 성공적으로 조회되었습니다."),
;

private final HttpStatus status;
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/noostak/group/domain/Groups.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.noostak.group.domain;

import java.util.Collections;
import java.util.List;

public class Groups {
private final List<Group> groups;

private Groups(List<Group> groups) {
this.groups = groups;
}

public static Groups of(final List<Group> groups) {
return new Groups(groups);
}

public List<Group> getGroups() {
return Collections.unmodifiableList(groups);
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
package org.noostak.group.dto.response;

import lombok.Builder;
import org.noostak.group.domain.Group;

@Builder
public record GroupCreateResponse(
Long groupId,
String groupName,
String groupProfileImageUrl,
String groupInvitationCode
) {
public static GroupCreateResponse of(final Group group, final String groupProfileImageUrl) {
{
return GroupCreateResponse.builder()
.groupId(group.getGroupId())
.groupName(group.getName().value())
.groupProfileImageUrl(groupProfileImageUrl)
.groupInvitationCode(group.getCode().value())
.build();
}
return new GroupCreateResponse(
group.getGroupId(),
group.getName().value(),
groupProfileImageUrl,
group.getCode().value()
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.noostak.group.dto.response;

import org.noostak.group.domain.Group;

public record GroupInternalRetrieveResponse(
Group group,
String groupProfileImageUrl
) {
public static GroupInternalRetrieveResponse of(final Group group, final String groupProfileImageUrl) {
return new GroupInternalRetrieveResponse(
group,
groupProfileImageUrl
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.noostak.group.dto.response;

import org.noostak.group.domain.Group;

public record GroupRetrieveResponse(
Long groupId,
String groupName,
Long groupMemberCount,
String groupProfileImageUrl
) {
public static GroupRetrieveResponse of(final Group group, final String groupProfileImageUrl) {
return new GroupRetrieveResponse(
group.getGroupId(),
group.getName().value(),
group.getCount().value(),
groupProfileImageUrl
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.noostak.group.dto.response;

import java.util.List;

public record GroupsRetrieveResponse(
List<GroupRetrieveResponse> groups
) {
public static GroupsRetrieveResponse of(final List<GroupRetrieveResponse> groupResponses) {
return new GroupsRetrieveResponse(groupResponses);
}
}
4 changes: 1 addition & 3 deletions src/main/java/org/noostak/infra/S3Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

public interface S3Service {
KeyAndUrl uploadImage(S3DirectoryPath dirPath, MultipartFile image) throws IOException;

String findImageUrl(String key);

String getImageUrl(String key);
void deleteImage(String key);
}
2 changes: 1 addition & 1 deletion src/main/java/org/noostak/infra/S3ServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public KeyAndUrl uploadImage(S3DirectoryPath dirPath, MultipartFile image) throw
}

@Override
public String findImageUrl(String key) {
public String getImageUrl(String key) {
return s3Storage.findPublicUrlByKey(key);
}

Expand Down
35 changes: 35 additions & 0 deletions src/main/java/org/noostak/membergroup/domain/MemberGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.noostak.membergroup.domain;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.noostak.global.entity.BaseTimeEntity;
import org.noostak.group.domain.Group;
import org.noostak.member.domain.Member;

@Entity
@Getter
@NoArgsConstructor
public class MemberGroup extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberGroupId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id")
private Group group;

private MemberGroup(final Member member, final Group groups) {
this.member = member;
this.group = groups;
}

public static MemberGroup of(final Member member, final Group group) {
return new MemberGroup(member, group);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.noostak.membergroup.domain;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface MemberGroupRepository extends JpaRepository<MemberGroup, Long> {

List<MemberGroup> findByMemberId(Long memberId);
}
42 changes: 19 additions & 23 deletions src/main/java/org/noostak/membergroup/domain/MemberGroups.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
package org.noostak.membergroup.domain;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.noostak.global.entity.BaseTimeEntity;
import org.noostak.group.domain.Group;
import org.noostak.member.domain.Member;
import java.util.Collections;
import java.util.List;

@Entity
@Getter
@NoArgsConstructor
public class MemberGroups extends BaseTimeEntity {
public class MemberGroups {
private final List<MemberGroup> memberGroups;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberGroupId;
private MemberGroups(List<MemberGroup> memberGroups) {
this.memberGroups = memberGroups;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
public static MemberGroups of(final List<MemberGroup> memberGroups) {
return new MemberGroups(memberGroups);
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id")
private Group group;
public List<MemberGroup> getMemberGroups() {
return Collections.unmodifiableList(memberGroups);
}

private MemberGroups(final Member member, final Group groups) {
this.member = member;
this.group = groups;
public List<Group> toGroups() {
return memberGroups.stream()
.map(MemberGroup::getGroup)
.toList();
}

public static MemberGroups of(final Member member, final Group group) {
return new MemberGroups(member, group);
public boolean isEmpty() {
return memberGroups.isEmpty();
}
}
Empty file.
Loading

0 comments on commit b22e4d7

Please sign in to comment.