๐ GitHub ๋ฐ๋ก๊ฐ๊ธฐ
API ๊ตฌ๋ถ | ๊ธฐ๋ฅ |
---|---|
์ ์ฒด๊ฒ์๊ธ ๋ชฉ๋ก์กฐํ | - ์ ๋ชฉ, ์์ฑ์๋ช
, ์์ฑ๋ด์ฉ, ์์ฑ๋ ์ง ์กฐํ - ์์ฑ๋ ์ง ๊ธฐ์ค ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ |
๊ฒ์๊ธ ์์ฑ | - ์ ๋ชฉ, ์์ฑ์๋ช
, ๋น๋ฐ๋ฒํธ, ์์ฑ๋ด์ฉ ์ ์ฅ - ์ ์ฅ๋๊ฒ์๊ธ Client ๋ฐํ |
์ ํํ๊ฒ์๊ธ ์กฐํ | - ์ ํํ๊ฒ์๊ธ ์ ๋ชฉ, ์์ฑ์๋ช , ์์ฑ๋ ์ง, ์์ฑ๋ด์ฉ ์กฐํ |
์ ํํ๊ฒ์๊ธ ์์ | - ์์ ์์ฒญ ์, ์์ ํ ๋ฐ์ดํฐ + ๋น๋ฐ๋ฒํธ โ ์๋ฒ์์ ๋น๋ฐ๋ฒํธ ์ ํจ์ฑ๊ฒ์ฌ - ์ ๋ชฉ, ์์ฑ์๋ช , ์์ฑ๋ด์ฉ ์์ - ์์ ๋๊ฒ์๊ธ Client ๋ฐํ |
์ ํํ๊ฒ์๊ธ ์ญ์ | - ์ญ์ ์์ฒญ ์, ๋น๋ฐ๋ฒํธ โ ์๋ฒ์์ ๋น๋ฐ๋ฒํธ ์ ํจ์ฑ๊ฒ์ฌ - ์ ํํ๊ฒ์๊ธ ์ญ์ - ์ฑ๊ณต๋ฉ์์ง Client ๋ฐํ |
๊ธฐ๋ฅ | Method | URL | Request | Response |
---|---|---|---|---|
๊ฒ์๊ธ์์ฑ | POST | /post | { ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "password" : "๋น๋ฐ๋ฒํธ", ย ย "content" : "์์ฑ๋ด์ฉ" } | { ย ย "id" : "๊ณ ์ ๋ฒํธ", ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "content" : "์์ฑ๋ด์ฉ", ย ย "createdAt" : "์์ฑ์๊ฐ", ย ย "modifiedAt" : "์์ ์๊ฐ" } |
์ ์ฒด๊ฒ์๊ธ๋ชฉ๋ก์กฐํ | GET | /posts | - | [ { ย ย "id" : "๊ณ ์ ๋ฒํธ", ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "content" : "์์ฑ๋ด์ฉ", ย ย "createdAt" : "์์ฑ์๊ฐ", ย ย "modifiedAt" : "์์ ์๊ฐ" }, { ย ย "id" : "๊ณ ์ ๋ฒํธ", ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "content" : "์์ฑ๋ด์ฉ", ย ย "createdAt" : "์์ฑ์๊ฐ", ย ย "modifiedAt" : "์์ ์๊ฐ" } ] |
์ ํํ๊ฒ์๊ธ์กฐํ | GET | /post/{post-id} | - | { ย ย "id" : "๊ณ ์ ๋ฒํธ", ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "content" : "์์ฑ๋ด์ฉ", ย ย "createdAt" : "์์ฑ์๊ฐ", ย ย "modifiedAt" : "์์ ์๊ฐ" } |
์ ํํ๊ฒ์๊ธ์์ | PUT | /post/{post-id} | { ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "password" : "๋น๋ฐ๋ฒํธ", ย ย "content" : "์์ฑ๋ด์ฉ" } | { ย ย "id" : "๊ณ ์ ๋ฒํธ", ย ย "title" : "์ ๋ชฉ", ย ย "username" : "์์ฑ์๋ช ", ย ย "content" : "์์ฑ๋ด์ฉ", ย ย "createdAt" : "์์ฑ์๊ฐ", ย ย "modifiedAt" : "์์ ์๊ฐ" } |
์ ํํ๊ฒ์๊ธ์ญ์ | DELETE | /post/{post-id} | { ย ย "password" : "๋น๋ฐ๋ฒํธ" } | { ย ย "status" : 200, ย ย "message" : "Deleted Post Successfully" } { ย ย "status" : ["The Post does not exist.", "Password is incorrect"] } |
@MappedSuperclass // ์กฐ์ํด๋์ค (but, Table์ค๊ณ X)
@Getter
@EntityListeners(AuditingEntityListener.class) // ํด๋น Entity ๋ณํ๊ฐ์ง -> ํ
์ด๋ธ๋ฐ์ดํฐ์กฐ์
public class Timestamped {
// ์์ฑ์๊ฐ
@CreatedDate
private LocalDateTime createdAt;
// ์์ ์๊ฐ
@LastModifiedDate
private LocalDateTime modifiedAt;
}
MallangLogApplication
โ @EnableJpaAuditing
์ถ๊ฐํ์@Entity
@Getter
@NoArgsConstructor // ํ๋ผ๋ฏธํฐ์๋ ๊ธฐ๋ณธ์์ฑ์
public class Post extends Timestamped {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String content;
}
// Client ์์ฒญ์ผ๋ก ๋ค์ด์ค๋ ์ ๋ณด๋ฅผ ๋ด๋ Dto
@Getter
public class PostRequestDto {
private String title;
private String username;
private String password;
private String content;
}
// Client Request ๊ฐ -> Dto์์ ๋ฐ์์์ -> ๋ฎ์ด์์
@Builder // ๋น๋ํจํด : ์์ฑ์๋ฅผ ํตํด ๊ฐ์ ๋ฐ์ (-> ์ ์ ํฉํ ๋ฆฌ๋ฉ์๋)
private Post(String title, String username, String password, String content) {
this.title = title;
this.username = username;
this.password = password;
this.content = content;
}
// ์ ์ ํฉํ ๋ฆฌ๋ฉ์๋
public static Post of(PostRequestDto postRequestDto) {
return Post.builder()
.title(postRequestDto.getTitle())
.username(postRequestDto.getUsername())
.password(postRequestDto.getPassword())
.content(postRequestDto.getContent())
.build();
}
// Post Entity ๊ฐ(๋ชจ๋ ๋ณ๊ฒฝ์ด ๋๋จ) getter -> Dto ๋ฎ์ด์์ด ํ -> Client์ ๋ฐํ
@Getter
public class PostResponseDto {
private Long id;
private String title;
private String username;
private String content;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
}
// ์์ฑ์
@Builder
private PostResponseDto(Long id,
String title, String username, String content,
LocalDateTime createdAt, LocalDateTime modifiedAt) {
this.id = id;
this.title = title;
this.username = username;
this.content = content;
this.createdAt = createdAt;
this.modifiedAt = modifiedAt;
}
// ์ ์ ํฉํ ๋ฆฌ๋ฉ์๋
public static PostResponseDto of(Post post) {
return PostResponseDto.builder()
.id(post.getId())
.title(post.getTitle())
.username(post.getUsername())
.content(post.getContent())
.createdAt(post.getCreatedAt())
.modifiedAt(post.getModifiedAt())
.build();
}
@RestController // @Controller + @ResponseBody -> JSONํํ ๋ฐ์ดํฐ๋ฐํ
@RequiredArgsConstructor // final, @Notnull ํ๋ -> ์์ฑ์์์ฑ
public class PostController {
private final PostService postService;
// Post ์์ฑ
@PostMapping("/post")
public PostResponseDto createPost(@RequestBody PostRequestDto postRequestDto) {
return postService.createPost(postRequestDto);
}
// ๋์จํ๊ฒฐํฉ : Entity ๋ฐ๋ก ๋ฐํ X, Dto์ ๋ด์ ๋ฐํ !
// @RequestBody : Client ์
๋ ฅ๊ฐ -> HTTP Body์ JSONํํ๋ก ์ง์ ๊ฐ์ฒด์ ๋ด์์ด
}
@Service
@RequiredArgsConstructor // final, @Notnull ํ๋ -> ์์ฑ์์์ฑ
public class PostService {
private final PostRepository postRepository;
// Post ์์ฑ
@Transactional // DB์ฒ๋ฆฌ ์์
์ค ์ค๋ฅ -> ๋ชจ๋ ์์
์์ํ๋ก ๋ณต๊ตฌ
public PostResponseDto createPost(PostRequestDto postRequestDto) {
// Entity ๊ฐ์ฒด ์์ฑ -> ์ ์ ํฉํ ๋ฆฌ๋ฉ์๋(์์ฑ์) ์ด๊ธฐํ
Post post = Post.of(postRequestDto);
// ์ด๊ธฐํ ๋ Entity ๊ฐ์ฒด -> Repository ์ ์ฅ
postRepository.save(post);
// ์ด๊ธฐํ ๋ Entity ๊ฐ์ฒด -> ResponseDto ์์ฑ์์ ์ ๋ฌ
return PostResponseDto.of(post);
}
}
๐ application.properties H2์ค์
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:db;MODE=MYSQL;
spring.datasource.username=mallang
spring.datasource.password=
<// Post ์ ์ฒด์กฐํ
@GetMapping("/posts")
public List<PostResponseDto> getPosts() {
return postService.getPosts();
}
// Post ์ ์ฒด์กฐํ
@Transactional(readOnly = true)
public List<PostResponseDto> getPosts() {
// Repository -> Entity ๊ฐ์ฒด๋ฐฐ์ด
List<Post> postList = postRepository.findAllByOrderByModifiedAtDesc();
// ResponseDto ๋ฐฐ์ด ์์ฑ
List<PostResponseDto> postResponseDtoList = new ArrayList<>();
// postList -> postResponseDtoList (List -> List๋ก ๋ฐ๋ก ๋ชป ์ฎ๊น)
for (Post post : postList) {
postResponseDtoList.add(PostResponseDto.of(post));
}
return postResponseDtoList;
}
// Post ์ ์ฒด์กฐํ (์์ฑ์๊ฐ๊ธฐ์ค ๋ด๋ฆผ์ฐจ์)
List<Post> findAllByOrderByModifiedAtDesc(); // ๋ฐํํ์
+ ์กฐ๊ฑด
// Post ์ ํ์กฐํ
@GetMapping("/post/{id}")
public PostResponseDto getSelectedPost(@PathVariable Long id) {
return postService.getSelectedPost(id);
}
// Post ์ ํ์กฐํ
@Transactional(readOnly = true)
public PostResponseDto getSelectedPost(Long id) {
// Repository -> Entity ๊ฐ์ฒด ๋ด์์ด -> ์์ธ์ฒ๋ฆฌ
Post selectedPost = postRepository.findById(id).orElseThrow(
// IllegalStateException : ์ ์ ํ์ง๋ชปํ ์ธ์๋ฅผ ๋ฉ์๋๋ก ๋๊ฒจ์ฃผ์์ ๋ ์์ธ
() -> new IllegalStateException("The Post does not exist.")
);
// Entity ๊ฐ์ฒด์ ๋ด์์จ ๊ฒ -> ResponseDto ์์ฑ์ ์ด๊ธฐํ -> Client ๋ฐํ
return PostResponseDto.of(selectedPost);
}
// Post ์์
@PutMapping("/post/{id}")
public PostResponseDto updatePost(@PathVariable Long id,
@RequestBody PostRequestDto postRequestDto) {
return postService.updatePost(id, postRequestDto);
}
// Post ์์
@Transactional
public PostResponseDto updatePost(Long id, PostRequestDto postRequestDto) {
// Entity ๊ฐ์ฒด ์์ฑ -> Repository์์ id๋ก ๋ถ๋ฌ์ด -> ์์ธ์ฒ๋ฆฌ
Post updatePost = postRepository.findById(id).orElseThrow(
() -> new IllegalStateException("The Post does not exist.")
);
// ๋น๋ฐ๋ฒํธ ์ ํจ์ฑ๊ฒ์ฌ
if (! postRequestDto.getPassword().equals(updatePost.getPassword())) {
throw new IllegalStateException("Password is incorrect");
}
// RequestDto -> ๋ถ๋ฌ์จ Entity์ ๋ฎ์ด์์
updatePost.update(postRequestDto);
// ์์ ์ด ๋๋ ๋ถ๋ฌ์จ Entity ๊ฐ์ฒด -> ResponseDto ์์ฑ์ ์ด๊ธฐํ -> Client ๋ฐํ
return PostResponseDto.of(updatePost);
}
// Post ์์ (Service -> RequestDto -> update ๋ฉ์๋)
public void update(PostRequestDto postRequestDto) {
this.title = postRequestDto.getTitle();
this.content = postRequestDto.getContent();
}
// Post ์ญ์
@DeleteMapping("/post/{post-id}")
public Map<Integer, String> deletePost(@PathVariable(name="post-id") Long postId,
@RequestBody PostRequestDto postRequestDto) {
return postService.deletePost(postId, postRequestDto);
}
// Post ์ญ์
@Transactional
public Map<Integer, String> deletePost(Long postId, PostRequestDto postRequestDto) {
// HashMap<key : value> -> ๋น๋ฐ๋ฒํธ ์ ํจ์ฑ ๊ฒ์ฌ ํ, ์ํ๋ฉ์์ง ๋ฐํ
Map<Integer, String> statusMessage = new HashMap<>();
// Entity ๊ฐ์ฒด ์์ฑ -> Repository์์ id๋ก ๋ถ๋ฌ์ด -> ์์ธ์ฒ๋ฆฌ
Post deletePost = postRepository.findById(postId).orElseThrow(
() -> new IllegalStateException("The Post does not exist")
);
// ๋น๋ฐ๋ฒํธ ์ ํจ์ฑ๊ฒ์ฌ -> ์ํ๋ฉ์์ง ๋ฐํ
if (postRequestDto.getPassword().equals(deletePost.getPassword())) {
postRepository.deleteById(postId);
statusMessage.put(200, "Deleted Post Successfully");
return statusMessage;
} else {
statusMessage.put(500, "Password is incorrect");
return statusMessage;
}
}