당니의 개발자 스토리
문제 본문
css의 선택자의 종류, 어떤 식으로 쓰는지 알고있어야 된다.
CSS 선택자 ⇒
#id
.class
p
p[name="a"]
:nth-child(2n) = :nth-child(even)
:nth-child(2n-1) = :nth-child(odd)
CSS에서 선택자는 HTML 요소를 선택해서 스타일을 적용하는 방법이에요. 각 선택자는 특정한 방식으로 요소를 지정해주는데, 그 종류는 여러 가지가 있어요.
먼저 #id 선택자는 id 속성으로 요소를 선택하는 거예요. 예를 들어, <div id="header">라는 요소가 있을 때, #header를 쓰면 그 요소를 선택할 수 있어요.
.class 선택자는 class 속성으로 요소를 선택해요. 예를 들어, <p class="text">라는 요소가 있으면, .text를 써서 그 요소를 선택할 수 있어요.
p는 태그 이름을 선택하는 거예요. <p> 요소 모두를 선택하게 돼요.
p[name="a"]는 특정 속성을 가진 요소를 선택하는 방법이에요. 여기선 <p name="a">인 요소를 선택하게 돼요.
:nth-child(2n)은 자식 요소 중에서 짝수 번째 요소를 선택해요. :nth-child(even)과 같은 효과를 가져요.
반대로 :nth-child(2n-1)은 홀수 번째 요소를 선택하는 거죠. :nth-child(odd)와 같은 의미에요.
이렇게 다양한 선택자를 적절하게 사용하면 원하는 요소에 스타일을 쉽게 적용할 수 있어요.

스타일의 이름
글꼴 스타일 지정 ⇒ font-style="normal|italic|..."
글꼴을 지정할 때 이런 것들이 온다고 보시면 되고.
글꼴 스타일을 지정할 때 사용하는 font-style 속성은 글자의 스타일을 설정하는 데 사용돼요.
예를 들어, font-style="normal"은 기본적인 스타일로 글꼴을 표시하고, font-style="italic"은 기울어진 이탤릭체로 글자를 표시해요.
이 외에도 font-style 속성에는 여러 값들이 있을 수 있어요.
예를 들어, oblique라는 값은 글꼴을 기울여서 표시하는데, italic과 비슷하지만 약간 다를 수 있어요.
기본적으로는 normal, italic, oblique 세 가지 스타일이 가장 많이 사용돼요.
글꼴 스타일을 설정하면 텍스트의 시각적인 표현을 다르게 할 수 있어서, 페이지의 분위기나 강조를 위해 유용하게 사용될 수 있어요.
반응형 웹 => @media를 쓰면 화면 크기에 따라서 다른 스타일을 적용할 수 있도록
미디어 쿼리 기억나냐, 해당하는 sql 문서가 보여질 디바이스 환경을 내가 지정할 수 있음.
상대 쿼리
반응형 웹 ⇒ @media ⇐ 화면 크기에 따라서 다른 스타일 적용
반응형 웹 디자인에서 @media는 화면 크기에 따라 다른 스타일을 적용할 수 있게 도와주는 기능입니다.
이를 통해 웹 페이지가 다양한 디바이스에서 잘 보이도록 조정할 수 있어요.
예를 들어 스마트폰, 태블릿, 컴퓨터 화면에서 각각 다르게 보이도록 설정할 수 있습니다. 미디어 쿼리를 사용하면 디바이스의 화면 크기나 해상도에 맞춰 스타일을 지정할 수 있어요. 이렇게 하면 여러 디바이스에서 최적화된 웹 페이지를 만들 수 있습니다.
상대쿼리는 고정된 크기 대신 변화하는 화면 크기나 디바이스 환경에 맞춰 웹 페이지가 동적으로 반응할 수 있도록 도와주는 역할을 해요.
선택자 중에서
nth-child(2n)가 있는데 2n 이라고 하면 n이 1부터 정수로 올라가는데 2, 4, 6
nth-child(2n-1)
nth-child(2n)은 2부터 시작해서 2씩 증가하는 요소들을 선택하는 선택자입니다. 여기서 n은 1부터 시작하는 정수로 증가합니다. 그래서 nth-child(2n)은 2, 4, 6, 8과 같이 짝수 번째 요소들을 선택하게 돼요.
반면에 nth-child(2n-1)은 조금 다르게 작동합니다. 이 선택자는 n 값에 따라 홀수 번째 요소들을 선택하는데요, 2n-1에서 n이 1부터 시작하면 결과적으로 1, 3, 5, 7과 같은 홀수 번째 요소들이 선택됩니다. 이는 2n에서 1을 빼면 홀수가 나오기 때문이에요.
form 태그
<form>
<input type="text">
<input type="number">
<input type="??????">
</form>
날짜를 받느냐 숫자를 받느냐에 따라서 넘버도 올 수 있고, 데이터도 올 수 있고 여러가지를 받을 수 있다고 했어요.
<form> 태그는 사용자가 데이터를 입력할 수 있는 폼을 만드는 데 사용돼요. 폼 안에는 여러 가지 입력 요소들이 들어가며, 각 입력 요소는 특정 타입을 지정할 수 있습니다.
<input> 태그는 여러 종류가 있는데, 예를 들어:
- <input type="text">는 일반적인 텍스트를 받는 필드예요.
- <input type="number">는 숫자만 받을 수 있는 입력 필드예요. 사용자가 숫자만 입력할 수 있도록 제한됩니다.
- <input type="date">는 날짜를 입력받을 수 있는 필드예요. 사용자가 달력에서 날짜를 선택할 수 있습니다.
그 외에도 다양한 입력 유형이 있는데요, 예를 들어:
- <input type="email">는 이메일 주소를 받을 수 있는 필드예요.
- <input type="password">는 비밀번호를 입력받을 수 있어, 입력한 내용이 숨겨져서 표시됩니다.
- <input type="file">은 파일을 선택할 수 있게 해주는 필드입니다.
즉, input 태그의 type 속성은 어떤 종류의 데이터를 받을지 정의하는 중요한 역할을 해요.
그리고 HTML5에는 article과 같은 의미를 나타내는 태그들이 추가되었다고 했습니다.
<article> 문서의 개별적인 / 독립적인 컨텐츠 </article>
어떤 내용이 담겼다라는 것을 태그를 통해서 전달함
독립적인 컨텐츠, 개별적인 컨텐츠를 article 이라고 합니다.
예를 들어 뉴스 기사, 블로그 글, 포럼의 게시물 같은 내용이 <article> 태그 안에 들어가게 됩니다.
이 태그는 그 자체로 하나의 독립적인 내용을 의미하며, 다른 곳에서 그 내용을 재사용하거나 독립적으로 이해할 수 있게 도와줍니다.
즉, <article> 태그는 문서에서 하나의 개별적인 콘텐츠를 표현하는 데 사용된다고 보면 됩니다.
var / let / const
예전에는 var를 사용했는데 es6에는 const랑 let이 추가됨
const는 한번 설정되면 변경할 수 없는 변수(상수), 즉 상수변수를 선언할 때 쓰는 것이 const 이다.
let은 변경가능한 수이다.
var, let, const는 변수를 선언할 때 사용합니다.
예전에는 var를 많이 썼지만, ES6부터는 let과 const가 추가되었습니다.
const는 한 번 설정되면 값을 변경할 수 없는 상수 변수를 선언할 때 사용합니다.
반면 let은 값이 변경 가능한 변수를 선언할 때 사용됩니다.
따라서 const는 변하지 않는 값, let은 변할 수 있는 값을 다룰 때 쓰는 것이죠.
var는 호이스팅 문제로 인해 예상치 못한 동작을 할 수 있습니다.
호이스팅은 변수가 선언되기 전에 사용될 수 있게 만드는 자바스크립트의 동작 방식인데, var로 선언한 변수는 함수나 전체 스코프에서 끌어올려지기 때문에 문제가 발생할 수 있습니다.
let과 const는 이런 호이스팅 문제를 해결하기 위해 도입되었습니다.
let과 const는 블록 스코프에서만 유효하기 때문에 코드가 예측 가능하고, 호이스팅 문제를 피할 수 있습니다.
따라서 var는 스코프 문제를 일으킬 수 있기 때문에, 이제는 let과 const를 사용하는 것이 좋습니다.
문자열 템플릿 리터럴 ⇒ ` `(백틱)
변수 값을 나타낼 때는 ${name} .... ${number + 1} 이런 식으로 할 수 있다.
가능하게 해주는 게 템플릿 리터럴 이다.
문자열 템플릿 리터럴은 백틱(`)을 사용해서 문자열을 만드는 방법입니다.
백틱 안에 변수를 넣고 싶으면 ${}를 사용해서 변수를 삽입할 수 있습니다.
예를 들어, ${name}처럼 작성하면 변수 name의 값이 문자열 안에 들어갑니다.
또한 계산식도 넣을 수 있어서 ${number + 1}처럼 작성하면 number에 1을 더한 값이 문자열 안에 포함됩니다.
이렇게 템플릿 리터럴을 사용하면 더 쉽게 문자열을 만들고 변수나 계산식을 포함시킬 수 있습니다.
내가 CORS 요청을 허용할 때 서버가 전달하는 응답 헤더 ⇒ Acess-control-alow-origin 등이 있지만 얘가 필수적으로 와야함.
그래서 서버가 준 리소스를 스크립트로 사용할 수 있음.
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS 여기서 답을 찾기.
CORS(Cross-Origin Resource Sharing)는 다른 도메인에서 요청을 보낼 때 서버가 이를 허용하는 방식입니다.
서버가 CORS 요청을 허용할 때, 반드시 응답 헤더에 Access-Control-Allow-Origin이 포함되어야 합니다.
이 헤더는 어떤 도메인에서 해당 리소스를 접근할 수 있는지를 정의하는데 사용됩니다.
예를 들어, Access-Control-Allow-Origin: *은 모든 도메인에서 접근을 허용하는 설정입니다.
이 헤더가 없다면 브라우저는 보안 상의 이유로 리소스를 사용할 수 없게 됩니다.
따라서 서버가 CORS 요청을 허용하려면 Access-Control-Allow-Origin 헤더를 반드시 응답에 포함시켜야 합니다.
화살표 함수
function add (a, b) {
return a + b;
}
이렇게 만들려면 익명 함수로 만든다.
const add = (a, b) => { return a + b; };
const add = (a, b) => a + b;
const add10 = a => a + 10;
매개변수랑 본문 사이에 화살표를 넣어준다.
문장이 하나이면 본문의 중괄호를 뺄 수 있고, return도 뺄 수 있다.
매개변수가 하나이면 소괄호도 생략 가능하다.
화살표 함수에서 리턴값이 없고 void 형태일 때도 본문이 한 줄이라면 중괄호를 생략할 수 없습니다.
기본 매개변수
function add (a, b = 1) { // 사용하지 않는 값을 기본 매개변수 라고 한다.
return a + b;
}
add(10, 20); // 30
add(10); // 11
기본 매개변수(default parameter)는 함수가 호출될 때 인자가 주어지지 않으면, 해당 매개변수에 기본값을 설정할 수 있는 기능
사전 요청을 보내지 않는 경우 = 단순 요청
Preflight 요청을 보내지 않는 경우 = 단순 요청
단순 요청을 하는 조건을 읽어 보세요!!! https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
단순 요청(Simple Request)은 CORS 요청 중에서 Preflight 요청을 보내지 않는 경우입니다. Preflight 요청은 요청을 보내기 전에 브라우저가 서버에 보내는 OPTIONS 요청인데, 단순 요청에서는 이런 단계가 생기지 않습니다.
단순 요청(Simple Request)이 되기 위한 조건
- HTTP 메서드가 GET, POST, HEAD 중 하나일 것
- PUT, DELETE, PATCH와 같은 메서드는 Preflight 요청을 발생시킵니다.
- 요청에 포함된 Content-Type
- application/x-www-form-urlencoded, multipart/form-data, text/plain 만 허용됩니다.
- 이 외의 Content-Type (예: application/json)은 Preflight 요청을 발생시킵니다.
- 허용된 헤더들만 포함될 것
- Accept, Accept-Language, Content-Language, Last-Event-ID와 같은 기본 헤더만 허용됩니다.
- 사용자가 정의한 헤더나 Authorization 같은 인증 관련 헤더는 Preflight 요청을 유발합니다.
- Request에 포함된 헤더가 위에 명시된 것들만 포함될 것
- 예를 들어, X-Custom-Header 같은 커스텀 헤더가 있다면 Preflight 요청이 발생합니다.
따라서 단순 요청은 위 조건들이 모두 만족되어야만 발생합니다.
그 외의 요청은 Preflight 요청을 통해 서버에 권한을 확인한 후 실제 요청이 이루어집니다.
위 조건을 모두 충족하는 경우에만 단순 요청으로 처리됩니다.
이 조건을 모두 만족하는 경우에는 브라우저가 Preflight 요청을 보내지 않고 바로 리소스를 요청하게 됩니다.
Preflight 요청을 보내지 않는 이유는 서버가 이미 정의된 규칙에 맞게 요청을 처리할 수 있다는 것을 의미합니다.
리액트 상태를 변경할 때 사용되는 함수 : useState
useState는 상태를 선언하고, 그 상태를 업데이트하는 함수를 반환합니다.

맨 왼쪽 마운트 단계
호출되는거 constructor, render, componentDidMount
이 사이클은 상세한거랑 상세하지 않은것 두가지를 전부 다 알고 계셔야 합니다.
useState는 초기값을 전달받고, 그 값을 기반으로 상태를 관리합니다.
setCount는 상태를 업데이트하는 함수로, 새 값을 전달하면 상태가 변경돼요.
리액트 컴포넌트의 생애 주기에서 마운트(Mount) 단계는 컴포넌트가 처음 화면에 렌더링될 때 일어나는 과정입니다. 이 과정에서 여러 함수들이 호출되는데, 그 함수들은 다음과 같습니다.
- constructor
컴포넌트가 처음 생성될 때 호출됩니다. 주로 초기 상태를 설정하거나, 메서드 바인딩을 할 때 사용됩니다. - render
constructor가 실행된 후에 호출됩니다. 이 함수는 컴포넌트의 JSX를 반환하며, 리액트가 화면에 렌더링할 내용이 결정됩니다. render는 상태나 props가 변경될 때마다 호출됩니다. - componentDidMount
컴포넌트가 화면에 마운트된 후에 한 번 호출됩니다. 이 단계에서 API 요청을 하거나 이벤트 리스너를 추가하는 등 초기화 작업을 할 수 있습니다. 한 번만 실행되기 때문에 주로 비동기 작업을 시작할 때 사용됩니다.
이 사이클을 알고 있으면 컴포넌트가 어떤 순서로 동작하는지 이해하는 데 도움이 됩니다.
상세하지 않은 것:
- constructor에서 상태 초기화만 하고, render가 실제 화면을 구성하며, componentDidMount는 컴포넌트가 마운트된 뒤 실행되는 단계입니다.
상세한 것:
- constructor는 컴포넌트의 초기화 시점을 잡아주고, render는 상태와 props를 기반으로 화면을 그리며, componentDidMount는 비동기 작업을 할 수 있는 안전한 시점입니다.
상세한 것은 리액트 컴포넌트 생애 주기에서 각 단계의 실행되는 시점과 그 용도를 깊이 있게 이해하는 것입니다.
상세하지 않은 것은 각 단계가 언제 실행되는지, 어떤 역할을 하는지를 간단히 아는 것과 같습니다
JSX에서 JavaScript 표현식을 사용할 때는 { }를 사용
<p> { name } </p>
<p> { number + 1 } </p>
<p> { numbers.map(n => ... ) } </p>
JSX에서는 JavaScript 표현식을 사용하려면 { }를 사용해야 합니다.
예를 들어, <p>{name}</p>는 name이라는 변수를 JSX 안에 표시하는 방법입니다.
<p>{number + 1}</p>처럼 수식도 { } 안에 넣어 사용할 수 있습니다.
또한 배열을 다룰 때는 <p>{numbers.map(n => ... )}</p>처럼 map 함수를 사용해 배열의 각 요소를 처리할 수 있습니다.
즉, { } 안에 JavaScript 코드를 넣으면 그 결과가 JSX로 변환되어 화면에 표시됩니다.
다 중괄호를 써서 표현을 한다.
라이프 사이클에서 상세로 뭐 하는지 알고계셔야 합니다.
업데이트 될때마다 실행되는건 DidUpdate

상세한 걸 보면 업데이트가 되지 않도록 하는 것도 있음 => shouldComponentUpdate
맞아요, 리액트에서 컴포넌트가 업데이트될 때마다 호출되는 함수는 componentDidUpdate입니다.
componentDidUpdate는 컴포넌트가 업데이트된 후, 즉 상태나 props가 변경된 후에 실행됩니다. 이 함수는 이전 상태나 props와 비교해서, 그에 맞는 후속 작업을 할 수 있게 도와줍니다.
그리고 shouldComponentUpdate라는 함수도 있습니다. 이 함수는 컴포넌트가 업데이트되기 전에 호출되어, 업데이트를 허용할지 말지를 결정합니다. 기본적으로는 업데이트가 이루어지지만, 이 함수에서 false를 반환하면 업데이트가 중지됩니다.
예를 들어, shouldComponentUpdate를 사용하면 성능 최적화를 할 수 있습니다. 자주 변경되지 않는 상태나 props를 확인하고 불필요한 렌더링을 막을 수 있기 때문입니다.
따라서 componentDidUpdate는 업데이트 후에 실행되고, shouldComponentUpdate는 업데이트 전에 실행되어 업데이트 여부를 결정합니다.
자바 쪽에 와서
자바의 주성분 알죠?
자바의 주석 쓰는 방법
자바에는 기본 데이터 타입이랑 참조 데이터 타입
Primitiv 원시 데이터 타입(기본 데이터 타입) 다 알고 계셔야 합니다.
⇒ https://www.w3schools.com/java/java_data_types.asp

- 기본 데이터 타입(Primitives)
- int: 정수
- double: 실수
- char: 문자
- boolean: 논리값 (true or false)
- long: 더 큰 정수
- float: 더 작은 실수
- byte: 아주 작은 정수
- short: 작은 정수
- 참조 데이터 타입(Reference Types)
- 클래스, 배열, 인터페이스 등이 여기에 해당합니다.
- 이들은 객체나 배열의 주소를 저장하며, 객체의 실제 데이터는 별도의 메모리 공간에 저장됩니다.
생성자(Constructor)
자바에서의 생성자는 클래스 이름과 똑같고 반환 타입이 있다 없다?
반환타입이 없다.
생성자는 명시적으로 호출하지 않으면 기본 생성자가 자동으로 호출됩니다.
숫자 데이터 타입에서
10 % 3 ⇒ 1
%는 나머지 연산자
배열 길이를 구할 때는 arr.length 해서 구할 수 있음.
컬렉션에 size나 length는 있는데, 배열에서는 length 속성을 이용해서 가져옵니다.
float a = 3.65;
하면 정확한 변수 선언은 X. 꼭 f를 붙여야 한다.
float a = 3.65F;
long b = 200L;
대문자든 소문자든 붙여줘야 한다.
int x = null; (안된다)
x는 원시 데이터 타입이기 때문에 null 이라는 건 힙 메모리의 주소가 결정되지 않았다는 거라서
reference 타입은 스택 영역에 변수가 잇곧 ㅔ이터는 실제로 힙에 있고 스택에는 힙 영역의 주소를 갖고 있음.
원시데이터는 힙에 생기지 않고 스택에 있기 떄문
int x = null; (안 된다)
x는 원시 데이터 타입이기 때문에 null을 할당할 수 없다
null은 객체가 없는 상태를 나타내는 값으로, 참조 타입에서만 사용된다. 즉, null은 힙 메모리 주소가 없음을 의미하는데, 원시 타입은 힙에 저장되지 않고 스택에 저장되기 때문이다.
참조 타입은 스택에 변수가 있고, 데이터는 힙에 저장되며, 스택에는 그 힙 주소가 저장된다
반면, 원시 데이터 타입은 값 자체가 스택에 저장되기 때문에 null 같은 주소 값을 할당할 수 없다
overring vs overloading
오버라이딩과 오버로딩은 둘 다 메서드를 다루는 개념이지만 목적이 다릅니다.
먼저 오버라이딩은 자식 클래스가 부모 클래스에 있는 메서드를 다시 정의하는 거예요. 부모 클래스에서 이미 정의된 메서드가 있고, 자식 클래스에서 그 메서드를 새롭게 구현하는 것이죠. 이렇게 하면 자식 클래스에서 부모 클래스의 메서드를 다르게 동작하게 만들 수 있어요.
반면 오버로딩은 같은 이름의 메서드를 여러 번 정의하는 거예요. 다만 매개변수의 갯수나 타입이 달라야 해요. 즉, 메서드 이름은 같지만, 입력받는 값이 다르면 그에 맞는 메서드를 자동으로 호출하게 됩니다.
간단히 말하면 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것이고, 오버로딩은 같은 이름의 메서드를 여러 개 정의하는 차이입니다.
스프링 부트를 시작할 때 main 메서드로부터 시작함.
모든 자바 프로젝트는 main 메서드에서부터 시작함.

main 안에서 run으로 스프링 어플리케이션을 실행한다.
@RestController는 REST API에서 데이터를 반환하는 거죠.
REST API에서 JSON 또는 XML 형식의 데이터를 반환하는 형식
Controller, Service, Mapper, Entity, Repository, Model, Dto
이 각각이 어떤 역할을 하는 객체인지를 알고 있어야 한다.
유저하고 접점 역할을 하는게 Controller 이다.
쿼리 매퍼의 메서드를 정의하는게 매퍼
엔티티는 jpa와 같은 orm을 사용할때 테이블과 맵핑되는 자바 객체
레파지토리는 그 엔티티를 db에 반영할 때 사용하는 인터페이스
모델은 데이터를 담고있는 객체
그 모델이 내부 로직에서 사용될 때는 DataTrasnferObject 라고해서 DTO로 불린다.
@Component는?
스프링에서 해당 클래스를 빈으로 자동 등록되게 해준다.
우리가 일반적으로 객체를 사용할 때는 new 해서 사용해야 하는데
바깥쪽에서 new 해서 넣어줘야되는 거죠.
dependency injection을 annotation 기반으로 빈으로 등록해줘야 합니다.
설정 클래스에서 @Configuration이 붙어있는 클래스 안에서 @Bean 해서 클래스를 반환하는 걸 정의해주면 되는데
별도의 설정 클래스 안에서 @Bean 안 붙여도 @Component가 붙어있는 클래스를 스프링이 자동으로 빈으로 등록해준다.
컴포넌트 스캔을 통해서 해준다.
@Component 빈으로 등록할 클래스를 정의해주는 겁니다.
@RequestMapping은 메인 메서드와 연결해주는 역할을 합니다.
@Transactional 트랜잭션 관리할 때 서비스와 같은 비즈니스 로직을 처리할 때 일괄적으로 처리되도록 보장해줌,
의존성 주입(DI)을 쓰는 이유
Dependecy Injection
의존이 많아지면 높은 결합이 생성되고, 그러면 의존 객체를 바꿀 때 사용객체도 바꿔줘야 하기 때문에
의존을 외부에서 생성해서 생성과정을 신경쓰지 않고 그냥 쓰면 된다. 객체 간의 결합도를 낮춰서 의존주입을 쉽게 해준다.
스프링 프레임워크에서 사용하는 객체를 빈
빈을 등록하고 관리하는 스프링 팩토리
빈은 어떤 스코프를 가진다고 했어요?
빈은 싱글톤 스코프를 가집니다.
getBean 해서 가지고 오면 인스턴스 찍으면
프로토타입 스코프라는 게 있는데 기본적으로 빈을 정의할 때 스코프를 지정하지 않으면 디폴트가 싱글톤 스코프다.
인스턴스가 하나만 생긴다.
시큐리티에서 사용자 인증정보를 저장하는 인터페이스는 유저 디테일스
유저 디테일스에서 어떻게 되어있는지
그것들은 어떻게 get, set 하는지
어떻게 인증을 할 것인지.
어떻게 가져갈 수 있는지 정의함
이 흐름에 맞춰서 인증을 처리
사용자 이름을 어디에서 가져가야 하는지, 사용자 패스워드를 어디에서 가져가야 하는지
정의해줘야 한다.
그리고 로그인 절차를 기술하고 있는 것이 유저 디테일 서비스

사용자 이름(식별자)을 가지고 사용자 이름이 있는지 없는지를 판단한다.
있으면 유저 디테일스를 반환한다. 로그인에 성공했다.
조회해서 스프링에서 관리하는 형식에 맞춰서 사용자 정보를 반환
인증 정보 패스워드가 자기들 내부에 가지고 있는게 맞는지를 비교함
REST API ⇒ GET / POST / PUT / DELETE
404 not found
503 에러 의미 잘 알고있어야 함
REST API를 설계할 때 엔드포인트
url에는 동사가 들어가는게 맞나요? 동사가 들어갑니다.
성숙도 모델에 보면

메서드가 분화되지 않았기 때문에 동사가 들어갑니다.
잘 만들어진 REST API 는 행위가 들어가지 않고
생성할거냐, 조회할거냐, 수정할거냐
동사가 들어가는 것은 좋은 명명 규칙은 아니다.
REST API 의 특징은 서버 클라이언트 구조이고,
중간에 architecture의 영향을 받지 않는다.
데이터베이스 정규화
데이터베이스 정규화는 Normalization.
db 정규화는 데이터의 중복을 제거하는 겁니다. 데이터의 무결성을 보장하기 위해서 정규화를 합니다.
기본 키(Key) = PK = Primary Key
기본 키의 주요 목적은 중복을 방지하고 그 데이터를 식별하기 위한 용도
JWT ⇒ header + payload + signature
JWT는 헤더와 페이로드, 그리고 시그니처 3가지 파트로 구성되어 있다.
헤더에는 토큰에 대한 구성정보가 들어감.
페이로드에는 넣어둔 데이터들
시그니처는 전체에 대한 서명 정보(검증을 위한)
페이로드에 들어있는 키-밸류 형태의 데이터를 claim 이라고 합니다.
JWT ⇒ header + payload + signature
~~~~~~~
claim → sub
claim에서 이건 이런 용도로 쓰여야 한다고 예약되어 있는 것 중에 sub가 있는데,
sub는 subject 라고 해서 이 토큰의 주체를 나타내는 용도로 사용됩니다.
sub 위주로 보기
iss (issuer): Issuer of the JWT
sub (subject): Subject of the JWT (the user)
aud (audience): Recipient for which the JWT is intended
exp (expiration time): Time after which the JWT expires
nbf (not before time): Time before which the JWT must not be accepted for processing
iat (issued at time): Time at which the JWT was issued; can be used to determine age of the JWT
jti (JWT ID): Unique identifier; can be used to prevent the JWT from being replayed (allows a token to be used only once)
Docker라고 하면 내가 만든 서비스를 환경정인, 실행 환경에서의 영향을 받지 않고
배포 할 수 있는 도구
마이크로 서비스의 장점과 단점도 알아두기
서비스 디스커버리를 구현할 때 사용했던 도구가 Eureka(유레카)
RabbitMQ은 우리가 다루진 않았는데 메시지 큐이다.
PostgreSQL ⇐ DB
ELK Stack ⇐ 로그
마이크로 서비스는 그 서비스의 조직, 어플리케이션 하나로 관리되는 것.
데이터가 한 곳에 중앙집중 될 수도 있지만 별도로 떨어져서 다른 곳에서 관리될수도 있음
다른 곳에서 호출해서 받아오는 방식도 있다.
우리가 내일 할
API GW 역할
이건 여러 서비스로 라우팅 할 수 있도록 해주는 겁니다.
주로 횡단 관심사
우리가 그런 것들을 적용할
로깅, 인간화 이런 것들을 공통적으로 적용하는 것
캐싱을 통해서 성능을 최적화 하는 거다.
SpringBoot에서 진입점이 되는 것은 스프링 어플리케이션에서 뭘로 시작하는지 어떻게 알까

이 @SpringBootApplication을 보고 스프링 프로젝트의 시작 클래스를 알 수 있다.