๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • What would life be If we had no courage to attemp anything?
Language/JavaScript

[JavaScript] API

by DevIseo 2023. 1. 16.

API

์‹œ์Šคํ…œ์ด ๋งŒ๋“ค์–ด ๋†“์€ ์„œ๋น„์Šค ์ฐฝ๊ตฌ

REST API

  • REpresentational State Transfer
  • ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฉ”์‹œ์ง€(๋ฐ์ดํ„ฐ) ํ˜•์‹
  • HTTP ๋ฉ”์„œ๋“œ(POST, GET, PUT, DELETE)๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์ž์›์— ๋Œ€ํ•œ CRUD๋ฅผ ์ ์šฉ

JSON Server๋ฅผ ์ด์šฉํ•œ REST API ์‹ค์Šต

1. JSON Server ์„ค์น˜

mkdir json-server-exam && cd json-server-exam
npm init -y
npm install json-server --save-dev

2. db.json ํŒŒ์ผ ์ƒ์„ฑ

/json-server-exam/db.json

{
    "todos":[
        {
            "id":1,
            "content":"HTML",
            "completed":true
        },
        {
            "id":2,
            "content":"CSS",
            "completed":false
        },
        {
            "id":1,
            "content":"JavaScript",
            "completed":true
        }
    ]
}

3. JSON Server ์‹คํ–‰

## ๊ธฐ๋ณธ ํฌํŠธ ์‚ฌ์šฉ(3000)/watch ์˜ต์…˜ ์ ์šฉ
json-server --watch db.json
## ํฌํŠธ ๋ณ€๊ฒฝ / watch ์˜ต์…˜ ์ ์šฉ
json-server --watch db.json --port 5000

4. package.json ์ˆ˜์ •

{
  "name": "json-server-exam",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1",
    **"start":"json-server --watch db.json"**
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "json-server": "^0.17.1"
  }
}

5. JSON Server ์‹คํ–‰

npm start

GET ์š”์ฒญ

json-server-exam/public/get_index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <pre></pre>
    <script>
        //XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ
        const xhr = new XMLHttpRequest()
        //HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
        //todos ๋ฆฌ์†Œ์Šค์— ๋ชจ๋“  todo๋ฅผ ์ทจ๋“(index)

				//์ „์ฒด
        xhr.open('GET','/todos')
        //์•„์ด๋”” ๊ฐ’
        xhr.open('GET','/todos/1')

        //HTTP ์š”์ฒญ ์ „์†ก
        xhr.send()

        //load ์ด๋ฒคํŠธ๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
        xhr.onload = () => {
            //status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ
            if(xhr.status ===200){
                document.querySelector('pre').textContent = xhr.response
            }else{
                console.error('Error',xhr.status,xhr.statusText)
            }
        }

    </script>
</body>
</html>

POST ์š”์ฒญ

  • POST ์š”์ฒญ ์‹œ์—๋Š” setRequestHeader ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MINE ํƒ€์ž… ์ง€์ •ํ•ด์•ผ ํ•จ

json-server-exam/public/post.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <pre></pre>
    <script>
        //XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ
        const xhr = new XMLHttpRequest()
        //HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
        //todos ๋ฆฌ์†Œ์Šค์— ์ƒˆ๋กœ์šด todo๋ฅผ ์ƒ์„ฑ
        
        xhr.open('POST','/todos')

        //์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MINE ํƒ€์ž…์„ ์ง€์ •
        xhr.setRequestHeader('content-type','application/json')

        //HTTP ์š”์ฒญ ์ „์†ก
        //์ƒˆ๋กœ์šด todo๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํŽ˜์ด๋กœ๋“œ๋ฅผ ์„œ๋ฒ„์— ์ „์†ก
        xhr.send(JSON.stringify({id:4, content:'Next.js',completed:false}))

        //load ์ด๋ฒคํŠธ๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
        xhr.onload = () => {
            //status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200(ok)๋˜๋Š” 201(created)์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ
            if(xhr.status ===200 || xhr.status==201){
                document.querySelector('pre').textContent = xhr.response
            }else{
                console.error('Error',xhr.status,xhr.statusText)
            }
        }
    </script>
</body>
</html>

PUT ์š”์ฒญ

  • ํŠน์ • ๋ฆฌ์†Œ์Šค ์ „์ฒด๋ฅผ ๊ต์ฒดํ•  ๋•Œ ์‚ฌ์šฉ
    • PUT ์š”์ฒญ์‹œ์—” setRequestHeader ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MINE ํƒ€์ž…์„ ์ง€์ •
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <pre></pre>
        <script>
            //XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ
            const xhr = new XMLHttpRequest()
            //HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
            //todos ๋ฆฌ์†Œ์Šค์— id๋กœ todo๋ฅผ ํŠน์ •ํ•˜์—ฌ id๋ฅผ ์ œ์™ธํ•œ ๋ฆฌ์†Œ์Šค ์ „์ฒด๋ฅผ ๊ต์ฒด
            xhr.open('PUT','/todos/4')
    
            //์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MINE ํƒ€์ž…์„ ์ง€์ •
            xhr.setRequestHeader('content-type','application/json')
    
            //HTTP ์š”์ฒญ ์ „์†ก
            //์ƒˆ๋กœ์šด todo๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํŽ˜์ด๋กœ๋“œ๋ฅผ ์„œ๋ฒ„์— ์ „์†ก
            xhr.send(JSON.stringify({id:4, content:'Next.js',completed:true}))
    
            //load ์ด๋ฒคํŠธ๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
            xhr.onload = () => {
                //status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200(ok)๋˜๋Š” 201(created)์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ
                if(xhr.status ===200){
                    document.querySelector('pre').textContent = xhr.response
                }else{
                    console.error('Error',xhr.status,xhr.statusText)
                }
            }
        </script>
    </body>
    </html>
    

DELETE ์š”์ฒญ

  • todos ๋ฆฌ์†Œ์Šค์—์„œ id๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ todo๋ฅผ ์‚ญ์ œ
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <pre></pre>
    <script>
        //XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ
        const xhr = new XMLHttpRequest()
        //HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
        //todos ๋ฆฌ์†Œ์Šค์— id๋ฅผ ์‚ฌ์šฉํ•ด todo ์‚ญ์ œ
        xhr.open('DELETE','/todos/4')

        //HTTP ์š”์ฒญ ์ „์†ก
        xhr.send()

        //load ์ด๋ฒคํŠธ๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
        xhr.onload = () => {
            //status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200(ok)๋˜๋Š” 201(created)์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ
            if(xhr.status ===200){
                document.querySelector('pre').textContent = xhr.response
            }else{
                console.error('Error',xhr.status,xhr.statusText)
            }
        }
    </script>
</body>
</html>

Reference

์ด์›…๋ชจ ์ €, ใ€Œ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Diveใ€, ์œ„ํ‚ค๋ถ์Šค(2020)

๋Œ“๊ธ€