
생애 최초 API만들기(1) (~5강)//서버개발개념, GET API개발
✨인프런 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! 라는 강의를 수강하면서 배운 점들을 정리하고있습니다.
강의초반 기록을 하던중 알게된건데 이미 pdf로 강의자료가 너무 잘정리되어있어서 강의 내용 요약은 의미가 없는거같고 각강의 별로 중요하게 기억해야 될만한거나 트러블슈팅,이해안돼서 추가로 알아본점 위주로 기록하고자한다. 🍁
(이번 섹션이 끝나고 답해보기)
1.스프링 프로젝트를 설정해 시작하고 실행할 수 있다,
2. 서버란 무엇인지, 네트워크와 HTTP,API는 무엇인지,JSON은 무엇인지 등 서버 개발에 필요한 다양한 개념을 이해한다.
3. 스프링 부트를 이용해 간단한 GET API,POST API를 만들 수 있다.
(시리즈 맨처음 스프링부트 초기세팅글에 기록해뒀음 초기세팅되어있으면 그냥 있는파일 열기만하면됨)
새로운 플젝을 시작하기 위해서는 https://start.spring.io 에 먼저 접속한다.

여기서 Project는 이 프로젝트에서 사용할 빌드툴을 선택한다.=>나는 Gradle을 사용함
Language는 서버를 개발할때 사용할 언어=>나는 Java사용
Spring Boot는 스프링 부트의 버전을 고르는 항목.알파벳이 붙어있으면 개발중이거나 오픈베타라는 의미
Group: 프로젝트 그룹
Artifact: 최종 결과물의 이름
Name: 프로젝트 이름
Description: 프로젝트 설명
Package name: 패키지 이름
을 각각 작성하면 된다.
packaging은 springboot는 톰캣이 내장되어있어 jar를 선택하면된다.(톰캣이 뭔지는 강의듣다보면 나옴)
java는 우리는지금java11로 개발중이지만 강의끝에쯤 17로 업그레이드할거임(강의가22년말강의라 강의자료에는 java 11과 java8도 선택할 수 있었지만 지금 24년 11월에는 java17까지만 선택할 수 있다.)

Dependencies - 의존성설정
의존성이란, 프로젝트에서 사용하는 라이브러리/프레임워크를 이야기함
(라이브러리= 프로그래밍을 개발할때 미리만들어져있는 기능을가져다 사용하는것)
(프레임워크= 프로그래밍을 개발할때 미리 만들어져있는 구조에 코드를 가져다 끼워 넣는 것)

지금은 강의에서 미리 제공해준 library app에서 작업할거기때문에 그파일은 의존성설정이 다되어있음 각 의존성에 대한 설명은 추후 나오게됨

generate하면 압축파일생성됨->압축해제하고 인텔리제이에서 압축해제한 파일을 찾아서 open

그다음부터는 똑같이 src/main/.../libraryapp/애플리케이션 파일 찾아서 프로젝트 실행하면됨
@SpringBootApplication
public class LibraryAppApplication {
public static void main(String[] args) {
SpringApplication.run(LibraryAppApplication.class, args);
}
}
이 코드에서 @SpringBootApplication은 어노테이션임. 어노테이션은 자바의 문법으로 @뒤에 여러 문자열을 붙이는것인데 종류에따라 하는일이 모두 다름
@SpringBootApplication은 스프링을 실행시키기 위해 필요한 다양한 설정을 자동으로 해줌.
코드의 마지막줄인 SpringApplication.run(LibraryAppApplication.class, args); 이것을 보면 스프링 애플리케이션을 실행하는 의미로 위의 전체코드는 우리의 서버를 실행시키는 코드이다.
그렇다면 이때 서버란?무엇일까
서버는 어떠한 기능을 제공하는프로그램/그 프로그램을 실행시키고있는 컴퓨터를 이야기한다.
예를들어 회원가입기능/정보가져오기기능/추천기능등의 기능을 사람말고 컴퓨터가 수행해주고 그 컴퓨터를 우리는 서버라고 부르는것.
컴퓨터가 이러한 기능을 하게하려면 요청을해야할텐데 컴퓨터에게 요청은 어떻게할까? 그 방법은 인터넷을 통해 요청을 보내는것이다. 다음강의에서 인터넷,네트워크에 대해 좀더 알아보자.

컴퓨터는 각각의 고유한 주소(IP)가 있음
데이터를 받는 컴퓨터를 IP 244.66.51.9, port:3000이라고 표현할수있음
(port는 컴퓨터안에서 사용하고있는 특정한 하나의 프로그램을 가르키는거임 즉 컴퓨터안에서 3000번 포트를 사용하는 프로그램은 하나니까 데이터를 주고받을때 그 프로그램으로 특정할수있게되는것 )
그러나 저 숫자 IP는 외우기 너무 어렵기때문에 Domain Name이 등장함 외우기 쉬운 이름을 넣는것 ex) spring.com ,port:3000
즉, IP 244.66.51.9= 도메인이름 spring.com 으로 표현할 수 있는것인데 이러한 네임시스템을 Domain Name System(DNS)라고 부름
강의에서는 네트워크를 택배시스템에 빗대어 설명하고 있는데 택배를 보내려면 운송장이 필요하다!
이러한 운송장은 당연히 표준이 있는데
이러한 운송장에는 운송장을 받는 사람에게 요청하는 행위/ 운송장이 가는집 / 운송장을 실제 받는사람/ 운송장을 받는 사람에게 원하는자원/ 자원의 세부조건 의 형태로 나타나게 된다.
내놓아라(행위)/파란집(가는집)/ 둘째(받는사람)/포션(자원)/빨강색 2개(세부조건)
창고에넣어라(행위)/빨간집(가는집,사람)/오크가죽(자원)/오크가죽이들어있는박스 이모지 (세부조건)
이때 행위와 자원은 빨간집에 운송장을 보내기전에 미리 약속해야한다! (빨간집이 어디인지 알고있어야된다던가 창고에 오크가죽을 넣을수있는 크기가 되야한다던가..등등
이런식으로 현실에서 데이터를 주고받을때도 표준이 있다.
이러한 표준을 HTTP(Hyper Text Transfer Protocol)이라고 한다. (protocol:표준,약속)
이거도 분석해 보자
GET/portion?color=red&count=2
Host: spring.com:3000
GET HTTP Method:요청을 받는 컴퓨터에게 요청하는 행위(데이터를 달라)
Host:spring.com:3000 HTTP요청을 받는 컴퓨터와 프로그램 정보 ex)빨간집
/portion Path: HTTP요청을 받는 컴퓨터에게 원하는 자원
? 구분기호
color=red 자원의 세부조건 (빨간색)
& 다른 세부조건와 구분하기위한 구분기호
count=2 자원의 세부 조건(개수는 2개)
정리해서 저 링크를 해석하면? -내놓아라 포션을 빨간색으로, 2개를 spring.com 3000번포트로 라는 문장이되겠다.
POST/oak/leather
Host:spring.com:3000 오크가죽정보
이것도 위에와 같은방식으로 해석할 수 있지만 실제 저장할 오크가죽 정보도 같이 전달한다. 이것도 문법이 필요해서 다음강의에 알려줄것.
위에 택배와 마찬가지로 행위와 자원은 HTTP요청을 보내기 전에 약속해야 한다!
post는 받는것이 아닌 보내는것이라 요청을 받는 컴퓨터가 값을 저장하게되는데 어떤데이터를 저장할지 /oak/leather라고 적어줬다. 실제로 저장할 오크가죽정보도 같이 보내주게되는데 이것을 Body라고 부른다.

GET : 데이터를달라,쿼리
POST : 데이터를저장하라,바디
추가적으로 다양한 HTTP Method가 있다.
PUT : 데이터를수정하라,바디
DELETE : 데이터를삭제하라,쿼리
빨간색 포션2개를 get해오려면 그것이 컴퓨터에 미리 저장되어있어야하고 오크가죽정보를 보내려면 받는 컴퓨터에서 오크가죽을 저장할 공간이 미리 있어야하는것 처럼
정해진 약속을하여, 특정한 기능을 수행하는것을 API라고 한다.

첫째줄은에서 쿼리는 get인경우에 추가된다. post기때문에 마지막줄에 body에 보낼 정보가 들어감
설명은 이미지에 적어둠
지금까지는 HTTP요청에 대해서만 다뤘는데 요청을받았으면 응답을줘야하기 때문에 알아보자!

초록 컴퓨터에서 파랑컴퓨터로 post요청을 보내면 파랑 컴퓨터는 정보를 처리한뒤 200ok라는 응답을 초록 컴퓨터에 보낸다.(200ok는 값이 잘 저장되었다는 응답)
즉 이렇게 요청에 저장이라는 기능을 하고 응답을 제공(serve)한 파랑컴퓨터가 바로 서버이다.
그리고 요청을한 초록컴퓨터가 바로 고객(Client)컴퓨터이다.
이러한 구조를 클라이언트-서버 구조라고한다.
응답에 들어가는 숫자(상태코드)는 매우 다양함.
200 ok /300 Moved Permanently(다른곳으로 옮겨가라)/404 NotFound(너가요청한걸 찾을수없다)/500 Internal Server Error(내부에 문제가 생김)
이러한 응답에는 바디를 통해 추가 정보를 담을 수도 있음 
HTTP응답역시 요청과 구조가 동일함

위의 설명을 듣고도 네트워크, HTTP, API가 정확히 무엇인지 헷갈려서 다시 비유를 통해 정리해봤다.
먼저 네트워크는 컴퓨터들끼리 연결된 길 같은것이다. 네트워크를 통해 통신하고 컴퓨터가 데이터를 주고받을 수있는것. 인터넷이 가장큰 네트워크이다.
HTTP는 네트워크(길)을 통해 데이터를 주고 받을때 사용하는 통신규칙(프로토콜)이다. 예를들자면 HTTP는 도로위에 교통법규같은것이다. 어떤데이터는 GET으로 요청받고 어떤 데이터는 POST로 요청을 보낸다와같은것들
마지막으로 API는 HTTP를 활용해서 클라이언트가 서버의 기능에 접근할 수 있도록 정의된 구체적인 규칙이다. 예를 들자면 API는 도로위에서 특정한 목적지로 가는 네비게이션 길안내 같은것. API는 이 url로 이렇게 요청하면 이러한 데이터를 줄게 라는 약속을 나타낸다.
(GPT의 정리)
네트워크: 길(도로) 자체.
컴퓨터들 간의 연결(인터넷, LAN 등).
HTTP: 도로 위의 교통 법규.
데이터를 주고받을 때 지켜야 할 기본 규칙.
예: "오른쪽 차선으로 주행하세요." → "GET으로 요청하세요."
API: 도로 위 특정 가게나 목적지를 찾는 방법.
클라이언트가 서버의 특정 기능에 접근하기 위한 상세한 지침.
예: "2번 출구에서 우회전하면 카페가 있습니다." → "GET /api/users/123 요청하면 특정 사용자 데이터를 반환합니다."
프론트를 공부해본 입장에서 개발쪽으로 이야기해보면 프론트엔드와 백엔드 간의 통신에서 HTTP는 데이터를 주고받는 기본적인 통신 규칙이고, API는 백엔드가 제공하는 기능이나 데이터를 프론트엔드에서 사용할 수 있도록 구체적으로 정의된 인터페이스이다.
드디어 실제로 api를 개발하고 테스트해보자!

api 구성요소 복습
이번강의에서는 간단하게 덧셈API를 만들어보자. 숫자두개를 보내면 덧셈결과가 반환되는...(초반에만 좀 자세히적고 툴다루는데 익숙해지면 모르는거위주로만ㄱㄱ)

LibraryAppApplication에서 우클릭>new>pakage만들고 controller라는 이름으로 패키지 생성
라이브러리앱이라는 패키지안에 컨트롤러라는 패키지가 생김

새로운파일 만드는 단축키는 폴더클릭하고 alt+insert임
API명세서를 만들기전 앞서 복습했던 API Specification (명세)들을 고려하고 만들어야된다. (API Spec이라고 줄여부름)

덧셈API는 값을 받아올거니 GET을 사용할거고 덧셈이니 /add, 정수 두개를 보내면 결과를 받아올 수 있게 할것이다.

package com.group.libraryapp.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CalculatorController {
@GetMapping("/add") //GET /add
public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2){
return number1 + number2;
}
}
@RestController :주어진Class를Controller로 등록한다. Controller : API의 입구
@GetMapping(“/add”) :아래함수를 HTTP Method가 GET이고 HTTP path가 /add인 API로 지정한다.
@RequestParam : 주어지는 쿼리를 함수 파라미터에 넣는다.
이제 Postman을 통해 API가 잘짜여졌는지 확인해보자!

내컴퓨터니까 로컬호스트를 넣고 스프링부트의 포트번호인8080까지넣어두면 그 이후는 파람에 키값을 넣으면 포스트맨이 자동으로 url을 만들어준다

send를 누르면 요청이 가서 그 결과인 30과 상태로 200 ok가 나온다!
현재는 쿼리에 들어오는 값이 number1과 number2로 2개이지만, API가 복잡해지면 @RequestParam이 매우 많아질 수도 있어, 결국 Controller에 있는 함수의 파라미터가 많아져야 한다는 뜻이다.
그렇기 때문에 매개변수에 객체를 받도록 개선해보자! (자세한설명 pdf참고)
com.group.libraryapp 패키지 안에 dto.calculator.request를 만들어주고, number1과 number2를 가지고 있는 클래스를 만들어 보자!

패키지,클래스 생성과 마찬가지로 Alt+insert로 코드를 전부 안쓰고 Constructor와 Getter를 만들 수 있음
package com.group.libraryapp.dto.calculator.request;
public class CalculatorAddRequest {
private final int number1;
private final int number2;
public CalculatorAddRequest(int number1, int number2) {
this.number1 = number1;
this.number2 = number2;
}
public int getNumber1() {
return number1;
}
public int getNumber2() {
return number2;
}
}
이렇게 코드를작성했으니 이제 Controller코드에서 이 클래스를 사용하도록 바꿔보자
파람을지우고 작성한 클래스를 적어주게되면 이 API를 호출할때 주어진 쿼리가 클래스 객체에 있는 값에 들어가게된다. return값도 객체로 한번 감싸서 받고있으니 request.으로 변경
package com.group.libraryapp.controller;
import com.group.libraryapp.dto.calculator.request.CalculatorAddRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CalculatorController {
@GetMapping("/add") //GET /add
public int addTwoNumbers(CalculatorAddRequest request) {
return request.getNumber1() + request.getNumber2();
}
}

새로쓴 코드에서도 잘작동된다.
요청 데이터를 객체로 묶어서 받아 관리가 간편해지고, 유지보수성이 향상됨
필요한 필드만 정의하면 되므로 코드가 간결해짐.
나중에 파라미터가 많아지더라도 @RequestParam int number1,@RequestParam int number2,@RequestParam int number3...이렇게 코드가 길어지지않고 DTO 객체에 필드를 추가만 하면 되므로 함수의 매개변수는 그대로 유지된다.
Alt+insert 패키지,클래스 등등 생성하는 단축키
ctrl+w 단어중간에 커서 두고 하면 드래그안해도 선택됨
ctrl+alt+o 안쓰는 임포트문 한번에 지우는 단축키