공부방

REST API 본문

스프링

REST API

코딩 화이팅 2023. 4. 25. 13:48

REST API는 "Representational State Transfer"의 약자로, 웹 기반 서비스에서 데이터와 기능을 공유하기 위해 사용되는 인터페이스입니다. 일반적으로 클라이언트와 서버 간에 정보를 주고받는 데 사용되며, 여러 언어와 플랫폼에서도 호환됩니다.

REST API는 다음과 같은 곳에서 주로 사용됩니다:

  1. 웹 서비스: 웹 사이트 또는 애플리케이션에서 다른 서비스와 데이터를 주고받을 때 REST API를 사용합니다. 예를 들어, 소셜 미디어 사이트에서 사용자의 프로필 정보나 게시물을 가져오거나, 온라인 상점에서 상품 목록과 가격 정보를 가져올 때 등입니다.
  2. 모바일 앱: 모바일 애플리케이션에서 서버와 통신하여 데이터를 주고받을 때 REST API를 사용합니다. 예를 들어, 날씨 앱에서 현재 날씨 정보를 가져오거나, 음악 스트리밍 앱에서 노래 정보를 가져오는 경우입니다.
  3. 마이크로서비스 아키텍처: 큰 시스템을 여러 작은 서비스로 나누어 구성하는 마이크로서비스 아키텍처에서, 서로 다른 서비스 간에 데이터와 기능을 주고받을 때 REST API를 사용합니다.
  4. IoT 디바이스: 인터넷에 연결된 디바이스들이 서버와 통신하여 데이터를 주고받을 때 REST API를 사용합니다. 예를 들어, 스마트 홈 시스템에서 가전제품의 상태를 가져오거나 제어하는 경우입니다.

REST API는 이러한 상황들 외에도 다양한 분야에서 데이터와 기능을 쉽게 공유할 수 있는 방법을 제공합니다.

 

REST 구성

  • 자원(Resource) : URI
  • 행위(Verb) : HTTP Method
  • 표현(Representations)
  • 잘 표현된 HTTP URL로 리소스를 정의하고 HTTP method로 리소스에 대한 행위를 정의한다. 리소스는 JSON, XML과 같은 여러가지 언어로 표현 가능

API(Application Programming Interface)

  • 두 소프트웨어 요소들이 서로 통신 할 수 있게 하는 방식(예 : 미세먼지 정보 제공 시스템)

프라이빗 API

기업 내부에 있으며 비즈니스 내에서 시스템과 데이터를 연결하는데 사용

퍼블릭 API

  • 일반에게 공개되며 누구나 사용 가능
  • 단, 사용에 대한 권한 설정과 비용이 있을수도 있다.
  • 공공데이터 포털, 기상청, Naver, Kakao, Youtube 등
  • 대부분이 REST 방식으로 작성

REST API(REST+API)

  •  기존의 전송방식과는 달리 서버는 요청으로 받은 리소스에 대해 순수한 데이터를 전송한다.
  • 기존의 GET/POST 외에 PUT,DELETE 방식을 사용하여 리소스에 대한 CRUD처리를 할 수 있다.
  • HTTP URI를 통해 제어할 자원을 명시하고, HTTP METHOD(GET/POST/PUT/DELETE)를 통해 해당 자원을 제어하는 명령을 내리는 방식의 Architecture이다.
  • 가장 큰 단점은 딱 정해진 표준이 없어 '다들 이렇게 쓰더라'정도의 암묵적인 표준만 정해져 있다.
    • 하이픈(-)은 사용 가능하지만 언더바는(_) 사용하지 않는다. ->둘 다 그냥 안 쓰는게 낫다.
    • 특별한 경우를 제외하고는 대문자 사용 X(대소문자 구분한다.)
    • URL 마지막에 슬래시(/)를 사용하지 않는다.
    • '/'로 계층 관계를 나타낸다.
    • 확장자가 포함된 파일 이름을 직접 포함시키지 않는다.
    • URI는 명사를 사용한다.

ResponseBody

package com.ssafy.rest.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ssafy.rest.model.dto.User;

@Controller
@RequestMapping("/rest1")
//원래는 @GetMapping("/rest1/test1")이라고 적어야하지만
//위와 같이 적어 @GetMapping("/test1")이렇게 줄여주고
//저 url로 바로 갈 수 있게 해준다.
public class TestController1 {
	//메소드를 쭉 작성할건데...
	
//	http://localhost:8080/mvc/rest1/test1 --> 404에러가 떴다. 뷰리졸버가 저이름을 뷰네임이라고 생각하고 경로를 만들어버리니
	@GetMapping("/test1")
	public String test1() {
		return "hi rest";
	}
}

package com.ssafy.rest.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ssafy.rest.model.dto.User;

@Controller
@RequestMapping("/rest1")
//원래는 @GetMapping("/rest1/test1")이라고 적어야하지만
//위와 같이 적어 @GetMapping("/test1")이렇게 줄여주고
//저 url로 바로 갈 수 있게 해준다.
public class TestController1 {
	//메소드를 쭉 작성할건데...
	
//	http://localhost:8080/mvc/rest1/test1 --> 404에러가 떴다. 뷰리졸버가 저이름을 뷰네임이라고 생각하고 경로를 만들어버리니
	@GetMapping("/test1")
	public String test1() {
		return "hi rest";
	}
	
//	http://localhost:8080/mvc/rest1/test2 --> @ResponseBody 붙였다. JSP 화면 그런거 반환이 아니라 데이터를 넘긴다.
	@GetMapping("/test2")
	@ResponseBody
	public String test2() {
		return "hi rest";
	}
}

Jackson 추가

mvnrepository에 들어가 jackson을 검색->Jackson Databind 가장 많은 다운로드가 있는 것 복사->pom.xml 붙여넣기

키와 값 형태인 json 출력

pom.xml
<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>

요거 추가
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.14.2</version>
		</dependency>
	</dependencies>
===================================================================
Testcontroller1.java
//	http://localhost:8080/mvc/rest1/test3 --> map을 반환하면 얘도 키 / 벨류니까 알잘로 JSON으로 바꾸어주지 않을까나?
	@GetMapping("/test3")
	@ResponseBody
	public Map<String, String> test3() {
		//Map은 키와 벨류를 가지고 있음.
		Map<String, String> data = new HashMap<>();
		
		data.put("id", "ssafy");
		data.put("password", "1234");
		data.put("name", "강현");
		
		return data; //jasckson을 추가했더니 요거 맵인데도 JSON으로 바꿔서 돌려주더라 오 good!
	}
}

DTO만들고 만든 객체 출력

User.java
package com.ssafy.rest.model.dto;

public class User {
	private String id;
	private String name;
	private String password;
	
	public User() {
	}
	
	public User(String id, String name, String password) {
		super();
		this.id = id;
		this.name = name;
		this.password = password;
	}

	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
	}
}
===================================================================
pom.xml
<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.14.2</version>
		</dependency>
===================================================================
TestController1.java
//	http://localhost:8080/mvc/rest1/test4 --> DTO 한번 반환해보자~~ 짹슨이 객체도 알아서 JSON형태로 바꾸어줘따
	@GetMapping("/test4")
	@ResponseBody
	public User test4() {
		User user = new User();
		user.setId("ssafy");
		user.setPassword("1234");
		user.setName("강현현");
		
		return user;
	}
}

많은 객체 데이터들을 한번에 출력

나머지 코드는 위와 동일
//	http://localhost:8080/mvc/rest1/test5 --> List 반환해보자. 자바스크립트의 배열 형태로 알잘로 바뀌어서 반환하더라
	@GetMapping("/test5")
	@ResponseBody
	public List<User> test5() {
		List<User> list = new ArrayList<>();
		
		for(int i = 1; i<=5; i++) {
			User user = new User();
			user.setId("ssafy"+i);
			user.setPassword("1234");
			user.setName("강현"+"bot"+i);
			list.add(user);
		}
		return list;
	}

RestController

기존에 있던 @ResponseBody를 다 없애주고 클래스 위에 @RestController만 붙여준다면 모든 메서드들이 @ResponseBody역할을 할 수 있게 된다.

package com.ssafy.rest.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ssafy.rest.model.dto.User;

@RestController
@RequestMapping("/rest2")
public class TestController2 {
	// 메소드를 쭉 작성할건데...

//	http://localhost:8080/mvc/rest2/test1 --> 404에러가 떴다. 뷰리졸버가 저이름을 뷰네임이라고 생각하고 경로를 만들어버리니
	@GetMapping("/test1")
	public String test1() {
		return "hi rest";
	}

//	http://localhost:8080/mvc/rest2/test2 --> @ResponseBody 붙였다. JSP 화면 그런거 반환이 아니라 데이터를 넘긴다.
	@GetMapping("/test2")
	public String test2() {
		return "hi rest";
	}

//	http://localhost:8080/mvc/rest2/test3 --> map을 반환하면 얘도 키 / 벨류니까 알잘로 JSON으로 바꾸어주지 않을까나?
	@GetMapping("/test3")
	public Map<String, String> test3() {
		// Map은 키와 벨류를 가지고 있음.
		Map<String, String> data = new HashMap<>();

		data.put("id", "ssafy");
		data.put("password", "1234");
		data.put("name", "양띵균");

		return data; // jasckson을 추가했더니 요거 맵인데도 JSON으로 바꿔서 돌려주더라 오 good!
	}

//	http://localhost:8080/mvc/rest2/test4 --> DTO 한번 반환해보자~~ 짹슨이 객체도 알아서 JSON형태로 바꾸어줘따
	@GetMapping("/test4")
	public User test4() {
		User user = new User();
		user.setId("ssafy");
		user.setPassword("1234");
		user.setName("유지나");

		return user;
	}

//	http://localhost:8080/mvc/rest2/test5 --> List 반환해보자. 자바스크립트의 배열 형태로 알잘로 바뀌어서 반환하더라
	@GetMapping("/test5")
	public List<User> test5() {
		List<User> list = new ArrayList<>();

		for (int i = 1; i <= 5; i++) {
			User user = new User();
			user.setId("ssafy" + i);
			user.setPassword("1234");
			user.setName("쾌지나" + "bot" + i);
			list.add(user);
		}
		return list;
	}

}

모든 메서드들이 위와 같은 출력이 나오고 원래 나오지 않았던 test1도 출력이 정상적으로 되게 한다.

Getmapping/Postmapping/Putmapping/Deletemapping

  • Getmapping : GET 요청을 처리하는 데 사용됩니다. 주로 서버에서 데이터를 조회할 때 사용하며, 클라이언트에게 정보를 제공합니다. 예를 들어, 게시물 목록이나 사용자 프로필 정보 조회와 같은 작업에 사용됩니다.
  • Postmapping : POST 요청을 처리하는 데 사용됩니다. 클라이언트가 서버에 새로운 데이터를 전송하고, 서버에서 이를 생성하거나 저장하는 작업에 사용됩니다. 예를 들어, 새 게시물 작성, 사용자 계정 등록 등에 사용됩니다.
  • Putmapping : PUT 요청을 처리하는 데 사용됩니다. 클라이언트가 서버에 기존 데이터를 전송하고, 서버에서 이를 수정하거나 업데이트하는 작업에 사용됩니다. 예를 들어, 게시물 수정, 사용자 프로필 정보 변경 등에 사용됩니다.
  • Deletemapping : DELETE 요청을 처리하는 데 사용됩니다. 서버에서 특정 데이터를 삭제하는 작업에 사용됩니다. 예를 들어, 게시물 삭제, 사용자 계정 삭제 등에 사용됩니다.
package com.ssafy.rest.controller;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/rest3")
public class TestController3 {
	@GetMapping("/test1")
	public String test1() {
		return "GET";
	}

	@PostMapping("/test2")
	public String test2() {
		return "POST";
	}

	@PutMapping("/test3")
	public String test3() {
		return "PUT";
	}

	@DeleteMapping("/test4")
	public String test4() {
		return "DELETE";
	}
}

PathVariable

package com.ssafy.rest.controller;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ssafy.rest.model.dto.User;

@RestController
@RequestMapping("/rest4")
public class TestController4 {
	
//	@PathVariable : URL 경로에 있는 값을 파라미터로 추출하겠다.
//	http://localhost:8080/컨텍스트루트/rest4/board/1
//	http://localhost:8080/컨텍스트루트/rest4/board/2
//	http://localhost:8080/컨텍스트루트/rest4/board/99  해당 글의 번호가 들어왔다.
	
	@GetMapping("/board/{id}")
	public String test1(@PathVariable int id) {
		return id + " : come on";
	}
}

만약 위처럼 파라미터 값과 쿼리스트링 값을 맞추고 싶지 않다면

@GetMapping("/board/{id}")
	public String test1(@PathVariable("id") int no) {
		return no + " : come on yo";
	}

이렇게 작성해도 출력은 똑같이 나온다.

게시글 등록하기

//	게시글 등록으로 해보자.
//	application/x-www-form-urlencoded :폼으로 넘기면 알아서 잘 들어가더라~~~
	@PostMapping("/board")
	public String test2(User user) {
		return user.toString();
	}

JSON형식으로 게시글을 등록하기->RequestBody

//JSON 형태로 값을 보내면 저기 user라고 하는 바구니에 넣어버리고 싶어!!
//	{
//		  "name" : "one paper push",
//		  "id" : "ssafy",
//		  "password" : "1234"
//		}
//	@RequestBody : 붙이면 JSON 데이터를 원하는 타입으로 바인딩
	@PostMapping("/board")
	public String test3(@RequestBody User user) {
		return user.toString();
	}

ResponseEntity

데이터 응답시 [상태코드, 헤더, 데이터] 설정이 가능

//ResponseEntity : 응답하려고 하는 데이터 / 응답 상태코드 / 응답 헤더같은것을 결정할수 있음
	@GetMapping("/test4")
	public ResponseEntity<String> test4(){
		HttpHeaders headers = new HttpHeaders();
		headers.add("auth", "admin");
		
		return new ResponseEntity<String>("OK", headers, HttpStatus.CREATED);
		
	}

간단한 예

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);

        if (user == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        return new ResponseEntity<>(user, HttpStatus.OK);
    }
}

이 예제에서는 getUserById 메서드를 통해 특정 사용자의 정보를 가져옵니다. 만약 사용자를 찾지 못한 경우, HttpStatus.NOT_FOUND(404) 상태 코드를 반환합니다. 사용자를 찾은 경우에는 사용자 정보와 함께 HttpStatus.OK(200) 상태 코드를 반환합니다.

'스프링' 카테고리의 다른 글

Rest API 예  (0) 2023.04.26
Swagger/CORS  (0) 2023.04.26
동적쿼리&트랜잭션  (0) 2023.04.21
MyBatis-Spring  (0) 2023.04.20
MyBatis  (0) 2023.04.19