GiantStepDEV
article thumbnail

REST API

๋จผ์ € REST๋ž€ 'Representational State Transfer'์˜ ์•ฝ์ž๋กœ, ์›”๋“œ ์™€์ด๋“œ ์›น(WWW)๊ณผ ๊ฐ™์€ ๋ถ„์‚ฐ ํ•˜์ดํผ๋ฏธ๋””์–ด ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜์˜ ํ•œ ํ˜•์‹ ์ž…๋‹ˆ๋‹ค. ์ฃผ๊ณ ๋ฐ›๋Š” ์ž์›(Resource)์— ์ด๋ฆ„์„ ๊ทœ์ •ํ•˜๊ณ  URI์— ๋ช…์‹œํ•ด HTTP๋ฉ”์†Œ๋“œ(GET, POST, PUT, DELETE)๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์ž์›์˜ ์ƒํƒœ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒƒ์„ ์˜๋ฏธ ํ•ฉ๋‹ˆ๋‹ค.

 

REST API๋Š” REST์•„ํ‚คํ…์ฒ˜๋ฅผ ๋”ฐ๋ฅด๋Š” ์‹œ์Šคํ…œ/์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. REST ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์›น ์„œ๋น„์Šค๋ฅผ 'RESTfulํ•˜๋‹ค'๋ผ๊ณ  ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

REST์˜ ํŠน์ง•

์œ ๋‹ˆํผ ์ธํ„ฐํŽ˜์ด์Šค

์œ ๋‹ˆํผ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์˜๋ฏธ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, REST ์„œ๋ฒ„๋Š” HTTP ํ‘œ์ค€ ์ „์†ก ๊ทœ์•ฝ์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ ๋งŒ๋“ค์–ด์กŒ๋А๋ƒ์™€ ์ƒ๊ด€์—†์ด ํ”Œ๋žซํผ ๋ฐ ๊ธฐ์ˆ ์— ์ข…์†๋˜์ง€ ์•Š๊ณ  ๋‹ค ํ˜ธํ™˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธ ํ•ฉ๋‹ˆ๋‹ค.

๋ฌด์ƒํƒœ์„ฑ(Stateless)

๋ฌด์ƒํƒœ์„ฑ์ด๋ž€ ์„œ๋ฒ„์— ์ƒํƒœ ์ •๋ณด๋ฅผ ๋”ฐ๋กœ ๋ณด๊ด€ํ•˜๊ฑฐ๋‚˜ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ ์ž…๋‹ˆ๋‹ค.

์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ์š”์ฒญ์— ๋Œ€ํ•ด ์„ธ์…˜์ด๋‚˜ ์ฟ ํ‚ค ์ •๋ณด๋ฅผ ๋ณ„๋„ ๋ณด๊ด€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ•œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ๋ณด๋‚ด๋“  ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ์š”์ฒญ์„ ๋ณด๋‚ด๋“  ๊ฐœ๋ณ„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ์ž์œ ๋„๊ฐ€ ๋†’๊ณ  ์„ค๊ณ„๊ฐ€ ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ

REST๋Š” HTTP ํ‘œ์ค€์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ HTTP์˜ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ ˆ์ด์–ด ์‹œ์Šคํ…œ

REST ์„œ๋ฒ„๋Š” ๋„คํŠธ์›Œํฌ ์ƒ์˜ ์—ฌ๋Ÿฌ ๊ณ„์ธต์œผ๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„์˜ ๋ณต์žก๋„์™€ ๊ด€๊ณ„์—†์ด ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ๋˜๋Š” ํฌ์ธํŠธ๋งŒ ์•Œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜

REST ์„œ๋ฒ„๋Š” API๋ฅผ ์ œ๊ณตํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๋กœ ๋ถ„๋ฆฌํ•ด ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ตฌ์„ฑ์€ ์„œ๋กœ์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ๋‚ฎ์ถ”๋Š” ๊ธฐ๋Šฅ์„ ํ•ฉ๋‹ˆ๋‹ค.

โญ๏ธREST์˜ URI ์„ค๊ณ„ ๊ทœ์น™

URI๋Š” ํŠน์ • ๋ฆฌ์†Œ์Šค๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ์‹๋ณ„์ž๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  1. URI์˜ ๋งˆ์ง€๋ง‰์—๋Š” '/'๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ์–ธ๋”๋ฐ” ๋Œ€์‹  ํ•˜์ดํ”ˆ(-)์„ ์‚ฌ์šฉ
  3. ํ–‰์œ„(๋™์‚ฌ)๊ฐ€ ์•„๋‹Œ ๊ฒฐ๊ณผ(๋ช…์‚ฌ)๋ฅผ ํฌํ•จ
  4. ์†Œ๋ฌธ์ž๋กœ ์ž‘์„ฑ
  5. ํŒŒ์ผ์˜ ํ™•์žฅ์ž๋Š” ํฌํ•จํ•˜์ง€ ์•Š์Œ

@RequestMapping์œผ๋กœ ๊ตฌํ˜„

@RestController
@RequestMapping("api/v1/get-api")
public class GetController {
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello() {
        return "Hello world";
    }
}

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” GET ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„

@RestController
@RequestMapping("api/v1/get-api")
public class GetController {
    @GetMapping(value ="/name")
    public String getHello() {
        return "Get : ๊ณฐ๋Œ์ด์‚ฌ์œก์‚ฌ";
    }
}

@PathVariable์„ ํ™œ์šฉํ•œ GET ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

@GetMapping(value = "/variable1/{variable}")
public String getVariable1(@PathVariable String variable) {
    return variable;
}

@GetMapping(value = "/variable2/{variable}")
public String getVariable2(@PathVariable("variable") String var) {
    return var;
}

@RequestParam์„ ํ™œ์šฉํ•œ GET ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

// http://localhost:8113/api/v1/get-api/request1?name=ddd&email=ddd2024@gmail.com&organization=kh
    @GetMapping(value = "/request1")
    public String getRequestParam(
            @RequestParam String name,
            @RequestParam String email,
            @RequestParam String organization) {
        return name + " " + email + " " + organization;
    }

@RestController์™€ @GetMapping์„ ์‚ฌ์šฉํ•œ JSON

package com.springboot.hello.controller;

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

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

@RestController
public class TestJsonController {
    @GetMapping("/members")
//    @ResponseBody : @RestController ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ์œผ๋ฉด ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ช…์‹œ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
    public List<Map<String, Object>> findMembers() {
        List<Map<String, Object>> members = new ArrayList<>();
        for(int i = 1; i <= 20; i++) {
            Map<String, Object> member = new HashMap<>();
            member.put("id", i);
            member.put("name", i + "๋ฒˆ ๊ฐœ๋ฐœ์ž");
            member.put("age", 10+ i);
            members.add(member);
        }
        return members;
    }
}
@RestController
public class MemberController {
    @GetMapping("/memberVO")
    public MemberVO member() {
        MemberVO vo = new MemberVO();
        vo.setId("ddd2024");
        vo.setPwd("!@#$df0");
        vo.setName("ํ™๊ธธ๋™");
        vo.setEmail("ddd2024@gmail.net");
        return vo;
    }
}
@GetMapping("/memberList")
    public List<MemberVO> listMember() {
        List<MemberVO> list = new ArrayList<>();
        for(int i = 0; i < 10; i ++) {
            MemberVO vo = new MemberVO();
            vo.setId("ddd" + i);
            vo.setPwd("@#$#df" + i);
            vo.setName("ํ™๊ธธ๋™" + i);
            vo.setEmail("ddd" + i + "@gmail.com");
            list.add(vo);
        }
        return list;
    }

@ResponseEntry ์‚ฌ์šฉํ•ด์„œ ์‘๋‹ตํ•˜๊ธฐ

@GetMapping("/membersList2")
public ResponseEntity<List<MemberVO>> listMember2() {
    List<MemberVO> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        MemberVO vo = new MemberVO();
        vo.setId("ddd");
        vo.setPwd("@$%#@df");
        vo.setName("ํ™๊ธธ๋™");
        vo.setEmail("ddd@gmail.com");
        list.add(vo);
    }
    return new ResponseEntity(list, HttpStatus.INTERNAL_SERVER_ERROR);
}

POST API ๋งŒ๋“ค๊ธฐ

@RequestMapping์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

@RestController
@RequestMapping("/api/v1/post-api")
public class PostController {
    @RequestMapping(value = "/domain", method = RequestMethod.POST)
    public String postExample() {
        return "Hello Post API";
    }
}

@RequestBody๋ฅผ ํ™œ์šฉํ•œ POST ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

@PostMapping(value = "/member")
public String postMember(@RequestBody Map<String, Object> postData) {
    StringBuilder sb = new StringBuilder();

    postData.entrySet().forEach(map -> {
        sb.append(map.getKey() + " : " + map.getValue() + "\n");
    });
    return sb.toString();
}

@ResponseEntity ์‚ฌ์šฉํ•ด์„œ ์‘๋‹ต

@GetMapping("/GetMemberParam")
public ResponseEntity <List<MemberVO>> memberList(@RequestParam String cmd) {
    if(cmd.equals("MemberList")) {
        MemberDAO dao = new MemberDAO();
        List<MemberVO> list = dao.memberSelect();
        return new ResponseEntity<>(list, HttpStatus.OK);
    } else {
        return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
    }
}
profile

GiantStepDEV

@kongmi

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!