서버 작업할때는
먼저 Postman에서 서버 리퀘스트 API를 먼저 생성해두고 작업합시다.
어떻게 처리하면 (Request) 원하는 결과가 나오는지 (Response) 바로 확인이 가능하니까!
API 명세서를 확인해서
요청사항을 파악한 후 Postman에서 이 API가 어떻게 작동해야할지 계획하고나서 코드를 작성한다.
책을 저장하는 API를 만든다고 생각해보자.
클라이언트가 책 정보들을 입력하면 서버가 저장을 하는 식으로 진행되겠지?
그런데 어떻게 입력하지?
JSON이란?
JSON(JavaScript Object Notation)은 데이터를 구조화하여 저장하거나 전송할 때 사용되는 경량 데이터 형식입니다. 간단하고 사람이 읽기 쉬운 텍스트 형식으로 데이터를 표현할 수 있으며, 특히 웹 애플리케이션에서 서버와 클라이언트 간 데이터를 주고받는 데 널리 사용됩니다.
json
{
"id": "string",
"title": "string",
"author": "string"
}
객체 (Object) 중괄호 {} 로 감싸인 키 - 값 쌍(pair)으로 구성
{
"과일": ["사과", "바나나", "체리"]
}
배열 (Array): 대괄호 [] 로 감싸인 키 - 값의 목록(List)으로 구성
자바에서의 arrayList, HashMap 과 닮았다.
Json데이터는 항상 키(String)와 값(String, Number, Boolean, Objcet, Array, null)으로 구성된다.
{
"recipes": [
{
"id": 1,
"name": "Egg Salad",
"description": "Place an egg in a saucepan and cover it with water. Bring to a boil, then reduce heat and simmer for 10-12 minutes. Cool the eggs, peel them, and mix with mayonnaise, mustard, salt, and pepper."
},
{
"id": 2,
"name": "Tomato Pasta",
"description": "Bring a large pot of lightly salted water to a boil. Add pasta and cook until al dente. In a separate pan, sauté garlic in olive oil, add chopped tomatoes, and simmer. Combine with pasta and serve."
}
]
}
키: recipes
객체: 각 레시피 객체는 id, name, description 속성을 가지고 있다
형식: JSON 형식은 중괄호 {}로 객체를 정의하고 대괄호 []로 배열을 정의
* JSON방식으로 리퀘스트를 하는것은 (=데이터를 보내는것은) put, post만 쓴다!
이렇게 HTTP 프로토콜을 통해 자원(Resource)의 상태를 주고받는 방식을 restful API 이라고 한다!
json
{
"id": "string",
"title": "string",
"author": "string"
}
랑 매칭되게 entitiy 클래스 변수를 선언한다.
package com.marurun66.book.entity;
import lombok.*;
//// getter setter 한번에 처리해주는 어노텐션 @Data - lombok 제공
//@Data
//// 기본 생성자 만들어주는 어노텐션 @NoArgsConstructor
//@NoArgsConstructor
//// 모든 파라미터 처리해주는 생성자 어노텐션 @AllArgsConstructor
//@AllArgsConstructor
public class Book {
private String id;
private String title;
private String author;
public Book() {
}
public Book(String id, String title, String author) {
this.id = id;
this.title = title;
this.author = author;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
lombok이 생성자, getter setter 모두 깔끔하게 지정이가능하다해서 기대가 컸는데
무슨 오류인지 적용이 안됨.
package com.marurun66.book.cotroller;
import com.marurun66.book.entity.Book;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
@RestController
public class BookController {
// 책을 저장하고, 가져오는 프로젝트
// API 명세서 확인 - 서로 주고받는 데이터
// 클라이언트에서 리퀘스트하면 서버에서는 이렇게 리스폰하라는 지침
// 기본 url http://localhost:8080/api/books
// Book ArrayList는 controller 담당이니 컨트롤러클래스에 생성자
ArrayList<Book> bookList = new ArrayList<>();
//CRUD
//2) 책 생성 (POST) R
@PostMapping("/api/books")
public Map<String, Object> createBook(@RequestBody Book book) {
// 클라이언트가 보내주는 데이터는 Book book에 저장
// 클라이언트는 joson으로 보내준다 = 묶음처리로 보내준다
// 그럼 고대로 받을 수 있는 클래스를 만들어준다 - Book클래스
// 근데 private네? Book클래스에서 getter setter를 롬복 @ 으로 설정해보자
//createBook 메서드에서 public Map<String, Object> createBook(@RequestBody Book book)는
// Book 객체를 받아서 처리한 후, 결과를 Map<String, Object> 형태로 반환하는 구조입니다.
bookList.add(book);
//클라이언트가 보낸 {
// "id": "B01",
// "title": "재밌는책",
// "author": "홍길동"
//}joson을 book에 저장하라
//응답
return Map.of("message", "created successfully", "book", book);
// key value
// book = id, title, author
// {} 에 들어간 데이터는 순서상관없이 출력된다 HashMap
}
//1) 책 조회 get C
@GetMapping("/api/books/{id}")
public Map<String, Object> getBook(@PathVariable String id) {
for (Book book : bookList) {
if (book.getId().equals(id)) {
return Map.of("book", book);
}
}
return Map.of("book", "해당 책이 없습니다.");
}
//3) 책 수정 put U
@PutMapping("/api/books/{id}") //id는 변수여서 {}
public Map<String, Object> updateBook(@PathVariable String id, @RequestBody Book book) {
//유저가 보내는 데이터가 파라미터로 들어가게 세팅
// 기존 책을 업데이트하는거니 기존책 먼저 찾기
for (Book savedBook : bookList) {
if (savedBook.getId().equals(id)) {
savedBook.setTitle(book.getTitle());
savedBook.setAuthor(book.getAuthor());
return Map.of("message", "Book updated successfully",
"book", savedBook);
}
}
return Map.of("message", "해당 책은 없습니다.");
}
//4) 책 삭제 delete D
@DeleteMapping("/api/books/{id}")
public Map<String, Object>deleteBook(@PathVariable String id) {
for (Book book : bookList) {
if (book.getId().equals(id)) {
bookList.remove(book);
return Map.of("message", "Book deleted successfully");
}
}
return Map.of("message", "해당 책은 없습니다.");
}
}