[{"data":1,"prerenderedAt":1533},["ShallowReactive",2],{"post-document:\u002Fbackend\u002Fspring\u002F2026\u002F08\u002F12\u002FREST_API_1\u002F":3},{"id":4,"title":5,"body":6,"categories":1519,"date":1522,"description":17,"extension":1523,"image":1524,"key_concepts":1524,"last_modified_at":1524,"legacyPath":1525,"meta":1526,"navigation":1300,"part":1524,"path":1528,"published":1300,"robots":1524,"seo":1529,"series":1524,"stem":1530,"strengths":1524,"summary":1524,"tags":1531,"tradeoffs":1524,"__hash__":1532},"posts\u002Fposts\u002FBackend\u002FSPRING\u002FREST_API\u002FREST_API_1.md","REST API의 개념과 설계 원칙",{"type":7,"value":8,"toc":1495},"minimark",[9,14,18,85,90,266,272,276,279,338,343,398,402,405,455,458,513,517,525,528,532,619,623,626,629,637,648,652,655,687,690,696,705,709,719,722,726,729,823,827,833,877,880,958,962,1048,1052,1055,1059,1062,1066,1069,1073,1084,1087,1091,1097,1100,1111,1115,1118,1138,1141,1144,1155,1161,1165,1168,1172,1175,1190,1196,1200,1235,1239,1242,1272,1276,1282,1315,1355,1359,1362,1368,1371,1382,1386,1389,1391,1402,1406,1491],[10,11,13],"h2",{"id":12},"웹-애플리케이션","웹 애플리케이션",[15,16,17],"p",{},"웹 애플리케이션은 클라이언트와 서버가 HTTP와 같은 통신 규칙을 사용해 데이터를 주고받으며 동작하는 프로그램입니다. 일반적으로 웹 브라우저나 모바일 앱을 통해 이용합니다.",[19,20,21,37],"table",{},[22,23,24],"thead",{},[25,26,27,31,34],"tr",{},[28,29,30],"th",{},"구분",[28,32,33],{},"설명",[28,35,36],{},"예시",[38,39,40,52,63,74],"tbody",{},[25,41,42,46,49],{},[43,44,45],"td",{},"클라이언트",[43,47,48],{},"서버에 요청을 보내고 응답을 받아 사용자에게 보여주는 프로그램",[43,50,51],{},"웹 브라우저, 모바일 앱",[25,53,54,57,60],{},[43,55,56],{},"프론트엔드",[43,58,59],{},"사용자가 직접 보고 조작하는 화면 영역",[43,61,62],{},"HTML, CSS, JavaScript, Angular, React, Vue.js",[25,64,65,68,71],{},[43,66,67],{},"서버",[43,69,70],{},"클라이언트의 요청을 처리하고 결과를 응답하는 프로그램",[43,72,73],{},"Java, Node.js, Python으로 구현한 애플리케이션",[25,75,76,79,82],{},[43,77,78],{},"백엔드",[43,80,81],{},"인증, 비즈니스 로직, 데이터 처리를 담당하는 서버 영역",[43,83,84],{},"Spring Boot, Express, Django",[86,87,89],"h3",{"id":88},"웹-애플리케이션의-주요-개념","웹 애플리케이션의 주요 개념",[19,91,92,105],{},[22,93,94],{},[25,95,96,99,102],{},[28,97,98],{},"개념",[28,100,101],{},"정의",[28,103,104],{},"쉬운 예시",[38,106,107,117,127,138,149,160,171,182,193,204,222,233,244,255],{},[25,108,109,111,114],{},[43,110,13],{},[43,112,113],{},"네트워크를 통해 사용자가 기능을 이용하는 프로그램",[43,115,116],{},"쇼핑몰, 게시판, 은행 사이트",[25,118,119,122,125],{},[43,120,121],{},"웹 클라이언트",[43,123,124],{},"서버에 요청을 보내는 사용자 측 프로그램",[43,126,51],{},[25,128,129,132,135],{},[43,130,131],{},"웹 서버",[43,133,134],{},"정적 리소스를 제공하거나 요청을 다른 서버로 전달하는 서버",[43,136,137],{},"HTML, CSS, JavaScript, 이미지 제공",[25,139,140,143,146],{},[43,141,142],{},"정적 리소스",[43,144,145],{},"미리 만들어져 있어 요청이 와도 내용이 크게 바뀌지 않는 파일",[43,147,148],{},"HTML, CSS, JavaScript, 이미지",[25,150,151,154,157],{},[43,152,153],{},"WAS",[43,155,156],{},"프로그램 로직을 실행하고 동적인 응답을 만드는 서버",[43,158,159],{},"JSP, Spring, Node.js 애플리케이션 실행",[25,161,162,165,168],{},[43,163,164],{},"데이터베이스(DB)",[43,166,167],{},"애플리케이션이 사용하는 데이터를 저장하고 관리하는 시스템",[43,169,170],{},"회원, 상품, 주문 정보 저장",[25,172,173,176,179],{},[43,174,175],{},"SQL",[43,177,178],{},"데이터베이스의 데이터를 조회하거나 변경하기 위한 언어",[43,180,181],{},"회원 조회, 상품 등록, 주문 수정",[25,183,184,187,190],{},[43,185,186],{},"HTTP 요청(Request)",[43,188,189],{},"클라이언트가 서버에 보내는 메시지",[43,191,192],{},"로그인, 상품 조회 요청",[25,194,195,198,201],{},[43,196,197],{},"HTTP 응답(Response)",[43,199,200],{},"서버가 요청을 처리한 뒤 클라이언트에 보내는 메시지",[43,202,203],{},"HTML, JSON, 상태 코드 반환",[25,205,206,209,212],{},[43,207,208],{},"Content-Type",[43,210,211],{},"메시지 본문에 담긴 데이터의 형식을 알려주는 HTTP 헤더",[43,213,214,218,219],{},[215,216,217],"code",{},"text\u002Fhtml",", ",[215,220,221],{},"application\u002Fjson",[25,223,224,227,230],{},[43,225,226],{},"API",[43,228,229],{},"서로 다른 프로그램이 정해진 방식으로 기능과 데이터를 사용할 수 있게 만든 접점",[43,231,232],{},"사용자 목록을 반환하는 서버 기능",[25,234,235,238,241],{},[43,236,237],{},"API Gateway",[43,239,240],{},"여러 백엔드 서비스로 요청을 전달하는 공통 진입점",[43,242,243],{},"Kong, Nginx, Spring Cloud Gateway",[25,245,246,249,252],{},[43,247,248],{},"모놀리식 아키텍처",[43,250,251],{},"여러 기능이 하나의 애플리케이션으로 구성된 구조",[43,253,254],{},"회원, 주문, 결제가 하나의 애플리케이션에 포함",[25,256,257,260,263],{},[43,258,259],{},"마이크로서비스 아키텍처",[43,261,262],{},"애플리케이션을 여러 개의 작은 서비스로 나눈 구조",[43,264,265],{},"회원 서비스, 주문 서비스, 결제 서비스 분리",[267,268,269],"blockquote",{},[15,270,271],{},"REST API는 API를 설계하는 방식이고, 마이크로서비스는 애플리케이션을 나누는 구조입니다. 따라서 모놀리식 애플리케이션도 REST API를 제공할 수 있습니다.",[86,273,275],{"id":274},"모놀리식-웹-애플리케이션-구조","모놀리식 웹 애플리케이션 구조",[15,277,278],{},"모놀리식 구조에서는 여러 기능이 하나의 애플리케이션 안에 함께 구성됩니다. 서버가 HTML을 만들어 응답하는 서버 사이드 렌더링 방식이 자주 사용됩니다.",[280,281,286],"pre",{"className":282,"code":283,"language":284,"meta":285,"style":285},"language-mermaid shiki shiki-themes github-light github-dark","flowchart LR\n    A[웹 브라우저\u003Cbr\u002F>모바일 앱] -->|HTTP 요청| B[웹 서버]\n    B -->|정적 요청| A\n    B -->|동적 요청| C[WAS\u003Cbr\u002F>JSP 또는 Spring]\n    C -->|데이터 조회 및 저장| D[(데이터베이스)]\n    D -->|조회 결과| C\n    C -->|HTML 응답| B\n    B -->|최종 응답| A\n","mermaid","",[215,287,288,296,302,308,314,320,326,332],{"__ignoreMap":285},[289,290,293],"span",{"class":291,"line":292},"line",1,[289,294,295],{},"flowchart LR\n",[289,297,299],{"class":291,"line":298},2,[289,300,301],{},"    A[웹 브라우저\u003Cbr\u002F>모바일 앱] -->|HTTP 요청| B[웹 서버]\n",[289,303,305],{"class":291,"line":304},3,[289,306,307],{},"    B -->|정적 요청| A\n",[289,309,311],{"class":291,"line":310},4,[289,312,313],{},"    B -->|동적 요청| C[WAS\u003Cbr\u002F>JSP 또는 Spring]\n",[289,315,317],{"class":291,"line":316},5,[289,318,319],{},"    C -->|데이터 조회 및 저장| D[(데이터베이스)]\n",[289,321,323],{"class":291,"line":322},6,[289,324,325],{},"    D -->|조회 결과| C\n",[289,327,329],{"class":291,"line":328},7,[289,330,331],{},"    C -->|HTML 응답| B\n",[289,333,335],{"class":291,"line":334},8,[289,336,337],{},"    B -->|최종 응답| A\n",[339,340,342],"h4",{"id":341},"동작-흐름","동작 흐름",[19,344,345,356],{},[22,346,347],{},[25,348,349,353],{},[28,350,352],{"align":351},"right","순서",[28,354,355],{},"과정",[38,357,358,366,374,382,390],{},[25,359,360,363],{},[43,361,362],{"align":351},"1",[43,364,365],{},"사용자가 웹 브라우저에서 웹 페이지를 요청합니다.",[25,367,368,371],{},[43,369,370],{"align":351},"2",[43,372,373],{},"웹 서버가 HTML, CSS, 이미지 같은 정적 리소스를 제공하거나 요청을 WAS로 전달합니다.",[25,375,376,379],{},[43,377,378],{"align":351},"3",[43,380,381],{},"WAS가 필요한 경우 데이터베이스에서 데이터를 조회하거나 저장합니다.",[25,383,384,387],{},[43,385,386],{"align":351},"4",[43,388,389],{},"WAS가 HTML 형태의 결과를 만들어 웹 서버에 전달합니다.",[25,391,392,395],{},[43,393,394],{"align":351},"5",[43,396,397],{},"웹 서버가 최종 HTML 응답을 브라우저에 전달합니다.",[86,399,401],{"id":400},"rest-api-기반-애플리케이션-구조","REST API 기반 애플리케이션 구조",[15,403,404],{},"REST API 기반 애플리케이션에서는 클라이언트가 서버에 JSON과 같은 표현 형식으로 데이터를 요청하고 응답받습니다. 클라이언트는 받은 데이터를 이용해 화면을 구성할 수 있습니다.",[280,406,408],{"className":282,"code":407,"language":284,"meta":285,"style":285},"flowchart LR\n    A[웹 클라이언트\u003Cbr\u002F>HTML CSS JavaScript] -->|초기 페이지 요청| B[웹 서버\u003Cbr\u002F>Vue.js 또는 React]\n    B -->|HTML CSS JS 이미지| A\n    A -->|HTTP 요청\u003Cbr\u002F>JSON 데이터| C[API Gateway]\n    C -->|서비스 요청 전달| D[백엔드 서비스\u003Cbr\u002F>Spring Boot Node.js Python]\n    D -->|데이터 조회 및 저장| E[(데이터베이스)]\n    E -->|조회 결과| D\n    D -->|JSON 응답| C\n    C -->|JSON 응답| A\n",[215,409,410,414,419,424,429,434,439,444,449],{"__ignoreMap":285},[289,411,412],{"class":291,"line":292},[289,413,295],{},[289,415,416],{"class":291,"line":298},[289,417,418],{},"    A[웹 클라이언트\u003Cbr\u002F>HTML CSS JavaScript] -->|초기 페이지 요청| B[웹 서버\u003Cbr\u002F>Vue.js 또는 React]\n",[289,420,421],{"class":291,"line":304},[289,422,423],{},"    B -->|HTML CSS JS 이미지| A\n",[289,425,426],{"class":291,"line":310},[289,427,428],{},"    A -->|HTTP 요청\u003Cbr\u002F>JSON 데이터| C[API Gateway]\n",[289,430,431],{"class":291,"line":316},[289,432,433],{},"    C -->|서비스 요청 전달| D[백엔드 서비스\u003Cbr\u002F>Spring Boot Node.js Python]\n",[289,435,436],{"class":291,"line":322},[289,437,438],{},"    D -->|데이터 조회 및 저장| E[(데이터베이스)]\n",[289,440,441],{"class":291,"line":328},[289,442,443],{},"    E -->|조회 결과| D\n",[289,445,446],{"class":291,"line":334},[289,447,448],{},"    D -->|JSON 응답| C\n",[289,450,452],{"class":291,"line":451},9,[289,453,454],{},"    C -->|JSON 응답| A\n",[339,456,342],{"id":457},"동작-흐름-1",[19,459,460,468],{},[22,461,462],{},[25,463,464,466],{},[28,465,352],{"align":351},[28,467,355],{},[38,469,470,477,484,491,498,505],{},[25,471,472,474],{},[43,473,362],{"align":351},[43,475,476],{},"웹 클라이언트가 웹 서버에서 화면에 필요한 정적 파일을 받습니다.",[25,478,479,481],{},[43,480,370],{"align":351},[43,482,483],{},"사용자가 버튼을 누르면 클라이언트가 API Gateway 또는 백엔드 API에 HTTP 요청을 보냅니다.",[25,485,486,488],{},[43,487,378],{"align":351},[43,489,490],{},"API Gateway가 요청을 적절한 백엔드 서비스로 전달합니다.",[25,492,493,495],{},[43,494,386],{"align":351},[43,496,497],{},"백엔드 서비스가 데이터베이스에서 데이터를 조회하거나 저장합니다.",[25,499,500,502],{},[43,501,394],{"align":351},[43,503,504],{},"백엔드 서비스가 JSON 형식으로 처리 결과를 반환합니다.",[25,506,507,510],{},[43,508,509],{"align":351},"6",[43,511,512],{},"웹 클라이언트가 JSON 데이터를 이용해 화면을 변경합니다.",[10,514,516],{"id":515},"rest란","REST란?",[15,518,519,520,524],{},"REST는 ",[521,522,523],"strong",{},"Representational State Transfer","의 줄임말입니다. 웹의 자원을 URI로 식별하고, HTTP 메서드로 자원에 수행할 작업을 표현하며, JSON이나 XML 같은 표현 형식으로 데이터를 주고받는 설계 방식입니다.",[15,526,527],{},"REST 자체는 특정 프로그래밍 언어나 프레임워크가 아닙니다. Spring Boot, Node.js, Django 등 어떤 기술로도 REST API를 만들 수 있습니다.",[86,529,531],{"id":530},"rest의-핵심-요소","REST의 핵심 요소",[19,533,534,548],{},[22,535,536],{},[25,537,538,541,544,546],{},[28,539,540],{},"요소",[28,542,543],{},"질문",[28,545,33],{},[28,547,36],{},[38,549,550,564,580,605],{},[25,551,552,555,558,561],{},[43,553,554],{},"Resource",[43,556,557],{},"무엇을 다룰 것인가?",[43,559,560],{},"서버가 제공하고 클라이언트가 조작하는 자원",[43,562,563],{},"사용자, 상품, 주문",[25,565,566,569,572,575],{},[43,567,568],{},"URI",[43,570,571],{},"자원을 어디에서 식별하는가?",[43,573,574],{},"자원을 고유하게 나타내는 주소",[43,576,577],{},[215,578,579],{},"\u002Fusers\u002F10",[25,581,582,585,588,591],{},[43,583,584],{},"HTTP Method",[43,586,587],{},"무엇을 할 것인가?",[43,589,590],{},"조회, 생성, 수정, 삭제 등의 행위를 표현",[43,592,593,218,596,218,599,218,602],{},[215,594,595],{},"GET",[215,597,598],{},"POST",[215,600,601],{},"PUT",[215,603,604],{},"DELETE",[25,606,607,610,613,616],{},[43,608,609],{},"Representation",[43,611,612],{},"어떤 형식으로 주고받는가?",[43,614,615],{},"자원을 표현한 데이터 형식",[43,617,618],{},"JSON, XML, HTML, 이미지",[86,620,622],{"id":621},"resource-자원","Resource: 자원",[15,624,625],{},"리소스(Resource)는 서버가 제공하고 클라이언트가 조작할 수 있는 대상입니다. 데이터 그 자체라기보다 데이터가 의미하는 개념을 자원으로 봅니다.",[15,627,628],{},"REST에서는 자원을 보통 명사로 표현합니다.",[280,630,635],{"className":631,"code":633,"language":634,"meta":285},[632],"language-text","User\nProduct\nArticle\nOrder\nReview\nImage\nSensorData\n","text",[215,636,633],{"__ignoreMap":285},[15,638,639,640,643,644,647],{},"예를 들어 사용자를 조회할 때 자원은 ",[215,641,642],{},"User","이고, 주문을 생성할 때 자원은 ",[215,645,646],{},"Order","입니다.",[86,649,651],{"id":650},"uri-자원의-식별자","URI: 자원의 식별자",[15,653,654],{},"URI(Uniform Resource Identifier)는 자원을 식별하는 주소입니다. URI는 어떤 자원을 다루는지를 표현하고, HTTP 메서드는 그 자원에 어떤 작업을 할지를 표현합니다.",[280,656,660],{"className":657,"code":658,"language":659,"meta":285,"style":285},"language-http shiki shiki-themes github-light github-dark","GET \u002Fusers\u002F10              # 10번 사용자 조회\nPUT \u002Fusers\u002F10              # 10번 사용자 전체 수정\nPATCH \u002Fusers\u002F10            # 10번 사용자 일부 수정\nDELETE \u002Fusers\u002F10           # 10번 사용자 삭제\nGET \u002Fusers\u002F10\u002Forders       # 10번 사용자의 주문 목록 조회\n","http",[215,661,662,667,672,677,682],{"__ignoreMap":285},[289,663,664],{"class":291,"line":292},[289,665,666],{},"GET \u002Fusers\u002F10              # 10번 사용자 조회\n",[289,668,669],{"class":291,"line":298},[289,670,671],{},"PUT \u002Fusers\u002F10              # 10번 사용자 전체 수정\n",[289,673,674],{"class":291,"line":304},[289,675,676],{},"PATCH \u002Fusers\u002F10            # 10번 사용자 일부 수정\n",[289,678,679],{"class":291,"line":310},[289,680,681],{},"DELETE \u002Fusers\u002F10           # 10번 사용자 삭제\n",[289,683,684],{"class":291,"line":316},[289,685,686],{},"GET \u002Fusers\u002F10\u002Forders       # 10번 사용자의 주문 목록 조회\n",[15,688,689],{},"URI는 동사보다 명사 중심으로 작성합니다.",[280,691,694],{"className":692,"code":693,"language":634,"meta":285},[632],"좋은 예: \u002Fusers\u002F10\n나쁜 예: \u002FcreateUser, \u002FupdateUser\n",[215,695,693],{"__ignoreMap":285},[15,697,698,218,701,704],{},[215,699,700],{},"create",[215,702,703],{},"update","와 같은 행위는 URI에 넣기보다 HTTP 메서드로 표현하는 것이 REST 방식에 더 적합합니다.",[339,706,708],{"id":707},"uri와-url의-차이","URI와 URL의 차이",[710,711,712,716],"ul",{},[713,714,715],"li",{},"URI: 자원을 식별하는 문자열이라는 넓은 개념입니다.",[713,717,718],{},"URL: 자원에 접근하는 방법과 위치까지 포함한 URI입니다.",[15,720,721],{},"실무에서는 두 용어가 비슷한 의미로 사용되기도 하지만, REST API의 엔드포인트를 설명할 때는 URI라는 표현을 자주 사용합니다.",[86,723,725],{"id":724},"http-method-자원의-행위","HTTP Method: 자원의 행위",[15,727,728],{},"자원을 조회, 생성, 수정, 삭제하는 CRUD 작업은 URI가 아니라 HTTP 메서드로 표현합니다.",[19,730,731,746],{},[22,732,733],{},[25,734,735,738,740,743],{},[28,736,737],{},"행위",[28,739,584],{},[28,741,742],{},"URI 예시",[28,744,745],{},"의미",[38,747,748,765,782,807],{},[25,749,750,753,757,762],{},[43,751,752],{},"생성(Create)",[43,754,755],{},[215,756,598],{},[43,758,759],{},[215,760,761],{},"\u002Fusers",[43,763,764],{},"새로운 사용자를 생성합니다.",[25,766,767,770,774,779],{},[43,768,769],{},"조회(Read)",[43,771,772],{},[215,773,595],{},[43,775,776],{},[215,777,778],{},"\u002Fusers\u002F1",[43,780,781],{},"1번 사용자 정보를 조회합니다.",[25,783,784,787,795,799],{},[43,785,786],{},"수정(Update)",[43,788,789,791,792],{},[215,790,601],{}," 또는 ",[215,793,794],{},"PATCH",[43,796,797],{},[215,798,778],{},[43,800,801,803,804,806],{},[215,802,601],{},"은 전체 수정, ",[215,805,794],{},"는 일부 수정을 의미합니다.",[25,808,809,812,816,820],{},[43,810,811],{},"삭제(Delete)",[43,813,814],{},[215,815,604],{},[43,817,818],{},[215,819,778],{},[43,821,822],{},"1번 사용자를 삭제합니다.",[86,824,826],{"id":825},"representation-자원의-표현","Representation: 자원의 표현",[15,828,829,830,832],{},"클라이언트는 서버에 있는 ",[215,831,642],{}," 객체 자체를 받는 것이 아니라, 그 자원을 표현한 데이터를 받습니다. 가장 많이 사용하는 표현 형식은 JSON입니다.",[280,834,838],{"className":835,"code":836,"language":837,"meta":285,"style":285},"language-json shiki shiki-themes github-light github-dark","{\n  \"id\": 10,\n  \"name\": \"홍길동\"\n}\n","json",[215,839,840,846,861,872],{"__ignoreMap":285},[289,841,842],{"class":291,"line":292},[289,843,845],{"class":844},"sVt8B","{\n",[289,847,848,852,855,858],{"class":291,"line":298},[289,849,851],{"class":850},"sj4cs","  \"id\"",[289,853,854],{"class":844},": ",[289,856,857],{"class":850},"10",[289,859,860],{"class":844},",\n",[289,862,863,866,868],{"class":291,"line":304},[289,864,865],{"class":850},"  \"name\"",[289,867,854],{"class":844},[289,869,871],{"class":870},"sZZnC","\"홍길동\"\n",[289,873,874],{"class":291,"line":310},[289,875,876],{"class":844},"}\n",[15,878,879],{},"대표적인 표현 형식은 다음과 같습니다.",[19,881,882,892],{},[22,883,884],{},[25,885,886,889],{},[28,887,888],{},"형식",[28,890,891],{},"용도",[38,893,894,902,910,918,926,934,942,950],{},[25,895,896,899],{},[43,897,898],{},"JSON",[43,900,901],{},"REST API에서 가장 일반적으로 사용하는 데이터 형식",[25,903,904,907],{},[43,905,906],{},"XML",[43,908,909],{},"태그 기반의 구조화된 데이터 형식",[25,911,912,915],{},[43,913,914],{},"YAML",[43,916,917],{},"설정 파일이나 사람이 읽기 쉬운 데이터 표현",[25,919,920,923],{},[43,921,922],{},"HTML",[43,924,925],{},"웹 브라우저 화면을 표현하는 문서 형식",[25,927,928,931],{},[43,929,930],{},"Text",[43,932,933],{},"단순한 문자열 데이터",[25,935,936,939],{},[43,937,938],{},"Image",[43,940,941],{},"JPG, PNG와 같은 이미지 파일",[25,943,944,947],{},[43,945,946],{},"Binary file",[43,948,949],{},"일반 파일이나 실행 파일 등 이진 데이터",[25,951,952,955],{},[43,953,954],{},"PDF",[43,956,957],{},"문서 파일",[10,959,961],{"id":960},"모놀리식-구조와-rest-api-기반-마이크로서비스-비교","모놀리식 구조와 REST API 기반 마이크로서비스 비교",[19,963,964,976],{},[22,965,966],{},[25,967,968,970,973],{},[28,969,30],{},[28,971,972],{},"모놀리식 구조",[28,974,975],{},"REST API 기반 마이크로서비스",[38,977,978,989,1000,1011,1026,1037],{},[25,979,980,983,986],{},[43,981,982],{},"구조",[43,984,985],{},"기능이 하나의 애플리케이션에 함께 구성",[43,987,988],{},"기능을 여러 서비스로 분리",[25,990,991,994,997],{},[43,992,993],{},"화면 응답",[43,995,996],{},"서버가 HTML을 만들어 응답",[43,998,999],{},"클라이언트가 화면을 만들고 JSON을 받음",[25,1001,1002,1005,1008],{},[43,1003,1004],{},"주요 통신",[43,1006,1007],{},"웹 서버와 WAS 중심",[43,1009,1010],{},"클라이언트, API Gateway, 여러 서비스 간 API 통신",[25,1012,1013,1016,1021],{},[43,1014,1015],{},"데이터 형식",[43,1017,1018,1019],{},"HTML, ",[215,1020,217],{},[43,1022,1023,1024],{},"JSON, ",[215,1025,221],{},[25,1027,1028,1031,1034],{},[43,1029,1030],{},"장점",[43,1032,1033],{},"구조가 단순하고 처음 배우기 쉬움",[43,1035,1036],{},"서비스별 개발, 배포, 확장이 쉬움",[25,1038,1039,1042,1045],{},[43,1040,1041],{},"단점",[43,1043,1044],{},"규모가 커지면 수정과 배포가 어려워질 수 있음",[43,1046,1047],{},"구조가 복잡하고 관리할 대상이 많음",[10,1049,1051],{"id":1050},"rest-설계-원칙","REST 설계 원칙",[15,1053,1054],{},"REST의 제약 조건을 지키면 클라이언트와 서버의 역할을 분리하고, 확장 가능한 웹 서비스를 설계하는 데 도움이 됩니다.",[86,1056,1058],{"id":1057},"_1-클라이언트와-서버의-분리","1. 클라이언트와 서버의 분리",[15,1060,1061],{},"클라이언트는 사용자 화면과 요청을 담당하고, 서버는 데이터와 비즈니스 로직을 담당합니다. 서로의 내부 구현을 몰라도 정해진 API를 통해 통신할 수 있어야 합니다.",[86,1063,1065],{"id":1064},"_2-무상태성stateless","2. 무상태성(Stateless)",[15,1067,1068],{},"무상태성이란 서버가 클라이언트의 이전 요청 상태를 저장하지 않는 특성입니다. 각 요청은 처리에 필요한 정보를 스스로 포함해야 하므로, 모든 요청은 서로 독립적입니다.",[339,1070,1072],{"id":1071},"필요한-정보의-예","필요한 정보의 예",[710,1074,1075,1078,1081],{},[713,1076,1077],{},"인증 정보",[713,1079,1080],{},"권한 정보",[713,1082,1083],{},"요청 처리에 필요한 데이터",[15,1085,1086],{},"이 정보는 HTTP 헤더, JWT, HTTP-Only Cookie 등의 방식으로 전달할 수 있습니다.",[339,1088,1090],{"id":1089},"상태-저장-방식과-rest-방식-비교","상태 저장 방식과 REST 방식 비교",[280,1092,1095],{"className":1093,"code":1094,"language":634,"meta":285},[632],"상태 저장 방식\n로그인 요청 → 서버가 세션 생성 → 이후 요청마다 서버가 세션 확인\n\n무상태 REST 방식\nGET \u002Fprofile\nHost: api.example.com\nAuthorization: Bearer eyJhbGciOi...\n\n서버는 이전 로그인 상태를 기억하지 않고, 현재 요청에 포함된 인증 정보를 확인\n",[215,1096,1094],{"__ignoreMap":285},[339,1098,1099],{"id":1099},"효과",[710,1101,1102,1105,1108],{},[713,1103,1104],{},"사용자별 세션을 특정 서버에 유지할 필요가 없어 서버 확장이 쉬워집니다.",[713,1106,1107],{},"여러 서버 중 어느 서버가 요청을 받아도 처리할 수 있습니다.",[713,1109,1110],{},"서버 내부 상태 관리가 줄어들어 시스템이 단순해집니다.",[86,1112,1114],{"id":1113},"_3-캐시-가능성cacheable","3. 캐시 가능성(Cacheable)",[15,1116,1117],{},"캐시는 한 번 받은 응답을 일정 시간 저장해 두었다가 다시 사용하는 기능입니다. REST에서는 응답이 캐시 가능한지, 얼마나 오래 사용할 수 있는지를 명확하게 표시합니다.",[280,1119,1121],{"className":657,"code":1120,"language":659,"meta":285,"style":285},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\nCache-Control: max-age=600\n",[215,1122,1123,1128,1133],{"__ignoreMap":285},[289,1124,1125],{"class":291,"line":292},[289,1126,1127],{},"HTTP\u002F1.1 200 OK\n",[289,1129,1130],{"class":291,"line":298},[289,1131,1132],{},"Content-Type: application\u002Fjson\n",[289,1134,1135],{"class":291,"line":304},[289,1136,1137],{},"Cache-Control: max-age=600\n",[15,1139,1140],{},"위 응답은 600초, 즉 10분 동안 재사용할 수 있다는 의미입니다. 브라우저, CDN, 프록시는 이 헤더를 기준으로 캐싱 여부를 판단합니다.",[339,1142,1099],{"id":1143},"효과-1",[710,1145,1146,1149,1152],{},[713,1147,1148],{},"같은 데이터를 다시 요청하는 네트워크 비용 감소",[713,1150,1151],{},"응답 속도 향상",[713,1153,1154],{},"서버 부하 감소",[15,1156,1157,1160],{},[215,1158,1159],{},"ETag","를 사용하면 데이터가 변경되었는지 확인한 뒤 변경되지 않은 경우 기존 캐시를 재사용할 수도 있습니다.",[86,1162,1164],{"id":1163},"_4-일관된-인터페이스uniform-interface","4. 일관된 인터페이스(Uniform Interface)",[15,1166,1167],{},"일관된 인터페이스는 모든 API가 예측 가능한 공통 규칙을 따르는 것을 의미합니다.",[339,1169,1171],{"id":1170},"자원의-식별","자원의 식별",[15,1173,1174],{},"자원은 명사 중심의 URI로 표현합니다.",[280,1176,1178],{"className":657,"code":1177,"language":659,"meta":285,"style":285},"GET \u002Fusers\u002F10\nGET \u002Forders\u002F2025\u002Fitems\n",[215,1179,1180,1185],{"__ignoreMap":285},[289,1181,1182],{"class":291,"line":292},[289,1183,1184],{},"GET \u002Fusers\u002F10\n",[289,1186,1187],{"class":291,"line":298},[289,1188,1189],{},"GET \u002Forders\u002F2025\u002Fitems\n",[280,1191,1194],{"className":1192,"code":1193,"language":634,"meta":285},[632],"잘못된 예: \u002FgetUserInfo, \u002FdoOrderCreate\n",[215,1195,1193],{"__ignoreMap":285},[339,1197,1199],{"id":1198},"표준-메서드-사용","표준 메서드 사용",[280,1201,1203],{"className":657,"code":1202,"language":659,"meta":285,"style":285},"GET \u002Fproducts       # 모든 상품 조회\nGET \u002Fproducts\u002F1     # 특정 상품 조회\nPOST \u002Fproducts      # 새로운 상품 생성\nPUT \u002Fproducts\u002F1     # 상품 정보 전체 수정\nPATCH \u002Fproducts\u002F1   # 상품 정보 일부 수정\nDELETE \u002Fproducts\u002F1  # 상품 삭제\n",[215,1204,1205,1210,1215,1220,1225,1230],{"__ignoreMap":285},[289,1206,1207],{"class":291,"line":292},[289,1208,1209],{},"GET \u002Fproducts       # 모든 상품 조회\n",[289,1211,1212],{"class":291,"line":298},[289,1213,1214],{},"GET \u002Fproducts\u002F1     # 특정 상품 조회\n",[289,1216,1217],{"class":291,"line":304},[289,1218,1219],{},"POST \u002Fproducts      # 새로운 상품 생성\n",[289,1221,1222],{"class":291,"line":310},[289,1223,1224],{},"PUT \u002Fproducts\u002F1     # 상품 정보 전체 수정\n",[289,1226,1227],{"class":291,"line":316},[289,1228,1229],{},"PATCH \u002Fproducts\u002F1   # 상품 정보 일부 수정\n",[289,1231,1232],{"class":291,"line":322},[289,1233,1234],{},"DELETE \u002Fproducts\u002F1  # 상품 삭제\n",[339,1236,1238],{"id":1237},"표준-표현-형식-사용","표준 표현 형식 사용",[15,1240,1241],{},"서버는 JSON, XML, YAML 등의 표준 형식으로 자원을 전달합니다.",[280,1243,1244],{"className":835,"code":836,"language":837,"meta":285,"style":285},[215,1245,1246,1250,1260,1268],{"__ignoreMap":285},[289,1247,1248],{"class":291,"line":292},[289,1249,845],{"class":844},[289,1251,1252,1254,1256,1258],{"class":291,"line":298},[289,1253,851],{"class":850},[289,1255,854],{"class":844},[289,1257,857],{"class":850},[289,1259,860],{"class":844},[289,1261,1262,1264,1266],{"class":291,"line":304},[289,1263,865],{"class":850},[289,1265,854],{"class":844},[289,1267,871],{"class":870},[289,1269,1270],{"class":291,"line":310},[289,1271,876],{"class":844},[339,1273,1275],{"id":1274},"자기-서술적-메시지self-descriptive-message","자기 서술적 메시지(Self-descriptive Message)",[15,1277,1278,1279,1281],{},"요청과 응답만 보더라도 메시지의 의미를 이해할 수 있어야 합니다. HTTP 메서드, URI, 상태 코드, ",[215,1280,208],{}," 등을 함께 사용하면 메시지를 더 명확하게 해석할 수 있습니다.",[280,1283,1285],{"className":657,"code":1284,"language":659,"meta":285,"style":285},"POST \u002Fusers HTTP\u002F1.1\nContent-Type: application\u002Fjson\n\n{\n  \"name\": \"홍길동\"\n}\n",[215,1286,1287,1292,1296,1302,1306,1311],{"__ignoreMap":285},[289,1288,1289],{"class":291,"line":292},[289,1290,1291],{},"POST \u002Fusers HTTP\u002F1.1\n",[289,1293,1294],{"class":291,"line":298},[289,1295,1132],{},[289,1297,1298],{"class":291,"line":304},[289,1299,1301],{"emptyLinePlaceholder":1300},true,"\n",[289,1303,1304],{"class":291,"line":310},[289,1305,845],{},[289,1307,1308],{"class":291,"line":316},[289,1309,1310],{},"  \"name\": \"홍길동\"\n",[289,1312,1313],{"class":291,"line":322},[289,1314,876],{},[280,1316,1318],{"className":657,"code":1317,"language":659,"meta":285,"style":285},"HTTP\u002F1.1 201 Created\nLocation: \u002Fusers\u002F10\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 10,\n  \"name\": \"홍길동\"\n}\n",[215,1319,1320,1325,1330,1334,1338,1342,1347,1351],{"__ignoreMap":285},[289,1321,1322],{"class":291,"line":292},[289,1323,1324],{},"HTTP\u002F1.1 201 Created\n",[289,1326,1327],{"class":291,"line":298},[289,1328,1329],{},"Location: \u002Fusers\u002F10\n",[289,1331,1332],{"class":291,"line":304},[289,1333,1132],{},[289,1335,1336],{"class":291,"line":310},[289,1337,1301],{"emptyLinePlaceholder":1300},[289,1339,1340],{"class":291,"line":316},[289,1341,845],{},[289,1343,1344],{"class":291,"line":322},[289,1345,1346],{},"  \"id\": 10,\n",[289,1348,1349],{"class":291,"line":328},[289,1350,1310],{},[289,1352,1353],{"class":291,"line":334},[289,1354,876],{},[86,1356,1358],{"id":1357},"_5-계층-구조layered-system","5. 계층 구조(Layered System)",[15,1360,1361],{},"클라이언트는 요청이 어떤 서버를 거쳐 최종 처리되는지 알 필요가 없습니다. 로드 밸런서, API Gateway, 인증 서버, 프록시 등 여러 중간 계층을 둘 수 있습니다.",[280,1363,1366],{"className":1364,"code":1365,"language":634,"meta":285},[632],"클라이언트 → API Gateway → 인증 서버 → 백엔드 서비스 → 데이터베이스\n",[215,1367,1365],{"__ignoreMap":285},[339,1369,1099],{"id":1370},"효과-2",[710,1372,1373,1376,1379],{},[713,1374,1375],{},"인증 서버를 분리해 보안을 강화할 수 있습니다.",[713,1377,1378],{},"로드 밸런싱과 캐싱을 적용할 수 있습니다.",[713,1380,1381],{},"API Gateway를 통해 여러 백엔드 서비스를 통합할 수 있습니다.",[86,1383,1385],{"id":1384},"_6-code-on-demand선택-사항","6. Code on Demand(선택 사항)",[15,1387,1388],{},"Code on Demand는 서버가 클라이언트에 실행 가능한 코드를 내려주고, 클라이언트가 이를 실행해 기능을 확장하는 방식입니다. REST의 다른 원칙과 달리 선택 사항입니다.",[339,1390,36],{"id":36},[710,1392,1393,1396,1399],{},[713,1394,1395],{},"브라우저에 새로운 JavaScript 파일을 내려줍니다.",[713,1397,1398],{},"클라이언트 업데이트 없이 새로운 입력 검증 기능을 추가합니다.",[713,1400,1401],{},"특정 페이지에서만 실행되는 동작을 내려줍니다.",[10,1403,1405],{"id":1404},"http-메서드별-rest-api-예시","HTTP 메서드별 REST API 예시",[19,1407,1408,1419],{},[22,1409,1410],{},[25,1411,1412,1415,1417],{},[28,1413,1414],{},"메서드",[28,1416,745],{},[28,1418,36],{},[38,1420,1421,1435,1449,1463,1477],{},[25,1422,1423,1427,1430],{},[43,1424,1425],{},[215,1426,595],{},[43,1428,1429],{},"조회",[43,1431,1432],{},[215,1433,1434],{},"GET \u002Fusers",[25,1436,1437,1441,1444],{},[43,1438,1439],{},[215,1440,598],{},[43,1442,1443],{},"생성",[43,1445,1446],{},[215,1447,1448],{},"POST \u002Fusers",[25,1450,1451,1455,1458],{},[43,1452,1453],{},[215,1454,601],{},[43,1456,1457],{},"전체 수정",[43,1459,1460],{},[215,1461,1462],{},"PUT \u002Fusers\u002F1",[25,1464,1465,1469,1472],{},[43,1466,1467],{},[215,1468,794],{},[43,1470,1471],{},"일부 수정",[43,1473,1474],{},[215,1475,1476],{},"PATCH \u002Fusers\u002F1",[25,1478,1479,1483,1486],{},[43,1480,1481],{},[215,1482,604],{},[43,1484,1485],{},"삭제",[43,1487,1488],{},[215,1489,1490],{},"DELETE \u002Fusers\u002F1",[1492,1493,1494],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":285,"searchDepth":298,"depth":298,"links":1496},[1497,1502,1509,1510,1518],{"id":12,"depth":298,"text":13,"children":1498},[1499,1500,1501],{"id":88,"depth":304,"text":89},{"id":274,"depth":304,"text":275},{"id":400,"depth":304,"text":401},{"id":515,"depth":298,"text":516,"children":1503},[1504,1505,1506,1507,1508],{"id":530,"depth":304,"text":531},{"id":621,"depth":304,"text":622},{"id":650,"depth":304,"text":651},{"id":724,"depth":304,"text":725},{"id":825,"depth":304,"text":826},{"id":960,"depth":298,"text":961},{"id":1050,"depth":298,"text":1051,"children":1511},[1512,1513,1514,1515,1516,1517],{"id":1057,"depth":304,"text":1058},{"id":1064,"depth":304,"text":1065},{"id":1113,"depth":304,"text":1114},{"id":1163,"depth":304,"text":1164},{"id":1357,"depth":304,"text":1358},{"id":1384,"depth":304,"text":1385},{"id":1404,"depth":298,"text":1405},[1520,1521],"Backend","Spring","2026-08-12 17:47:59 +0900","md",null,"\u002Fbackend\u002Fspring\u002F2026\u002F08\u002F12\u002FREST_API_1\u002F",{"layout":1527},"post","\u002Fposts\u002Fbackend\u002Fspring\u002Frest_api\u002Frest_api_1",{"title":5,"description":17},"posts\u002FBackend\u002FSPRING\u002FREST_API\u002FREST_API_1",[],"B1wDxwE0nRqn8qczaWM05xbL6-cYEZZw7fkAcGu3F_U",1788744786041]