RestFul API

๊ด€๋ จ ํ‚ค์›Œ๋“œ๊ฐ€ ํฌํ•จ๋œ ๋‰ด์Šค ๊ฒ€์ƒ‰ API ๋งŒ๋“ค๊ธฐ

567Rabbit 2024. 5. 29. 17:10

 

ํ‚ค์›Œ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•œ ๋‰ด์Šค๋ฅผ ๋‚˜์˜ค๊ฒŒ ํ•˜๋Š” ๋‰ด์Šค ๊ฒ€์ƒ‰ API๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

 

API ๋งŒ๋“ค๊ธฐ ์ „์—, ๊ธฐ๋ณธ ์…‹ํŒ… ํ•˜๊ธฐ

 

 

(1). serverless๋กœ aws-openapi-server๋ฅผ ๋งŒ๋“ค๊ณ  vscode๋กœ ์—ด์–ด์ฃผ์—ˆ๋‹ค.

 

https://codebunny99.tistory.com/105

 

RestFul API๋ฅผ Serverless Framework๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ

*** ์•„๋‚˜์ฝ˜๋‹ค ํ”„๋กฌํ”„ํŠธ์—์„œ ๊ฐ€์ƒํ™˜๊ฒฝ ๋งŒ๋“ค๋ฉด์„œ flask์— ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด ๋ฐ›์•„์ค€๋‹ค *** conda create -n lambda_310 python=3.10pip install flask flask-restful mysql-connector-python psycopg2-binary passlib flask-jwt-exte

codebunny99.tistory.com

 

 

 

 

 

(2). ๋„์ปค ์„ค์ •์„ ํ•ด์ค€๋‹ค.

 

https://codebunny99.tistory.com/108

 

AWS ์„œ๋ฒ„ ์—ฐ๊ฒฐ ์‹œ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์šฉ๋Ÿ‰ ์ค„์—ฌ์ฃผ๋Š” Docker(๋„์ปค) ์„ค์น˜ํ•˜๊ธฐ

https://www.docker.com/products/docker-desktop/ Docker Desktop: The #1 Containerization Tool for Developers | DockerDocker Desktop is collaborative containerization software for developers. Get started and download Docker Desktop today on Mac, Windows, or

codebunny99.tistory.com

 

 

 

 

(3). ๊นƒํ—ˆ๋ธŒ์™€ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.

 

https://codebunny99.tistory.com/106

 

Serverless๋กœ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ ํด๋”๋ฅผ ๊นƒํ—ˆ๋ธŒ(Github)์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ

cmd(๋ช…๋ นํ”„๋กฌํ”„ํŠธ)   serverless ๋ผ๊ณ  ์ž…๋ ฅํ•œ๋‹ค serverless   ๋ฐฉํ–ฅํ‚ค๋กœ Flask API๋กœ ์ด๋™ํ•œ๋‹ค         ๊นƒํ—ˆ๋ธŒ(Github)   New repositoryํ•˜๊ธฐ    VSCode  VSCode Serverless๋กœ ์•„๊นŒ ๋งŒ๋“  ํด๋” ์—ด๊ณ , ๊ฐ€์ƒํ™˜๊ฒฝ

codebunny99.tistory.com

 

 

 

 

(4). ๊นƒํ—ˆ๋ธŒ ์•ก์…˜์ฆˆ ์„ค์ •์„ ํ•œ๋‹ค.

 

https://codebunny99.tistory.com/107

 

Serverless๋กœ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ๋ฅผ ๊นƒํ—ˆ๋ธŒ ์•ก์…˜์ฆˆ(Github actions)๋กœ ์ž๋™ํ™”ํ•˜๊ธฐ

์‚ฌ์šฉํ•  repository๋ฅผ ํด๋ฆญํ•˜๊ณ  Settings๋กœ ์ด๋™ํ•œ๋‹ค.     Settings์—์„œ Security -> secrets and variables -> Actions๋กœ ์ด๋™ํ•˜๊ณ  New repository secret ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค.      https://codebunny99.tistory.com/104 ์™„๋ฃŒ    

codebunny99.tistory.com

 

 

 

 

API ์ƒ์„ฑํ•˜๊ธฐ

 

 

๋จผ์ € API์— ๋Œ€ํ•œ ์„ค๋ช…์„ ๋ฐ‘์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.

 

https://developers.naver.com/docs/serviceapi/search/news/news.md#%EB%89%B4%EC%8A%A4

 

๊ฒ€์ƒ‰ > ๋‰ด์Šค - Search API

๊ฒ€์ƒ‰ > ๋‰ด์Šค ๋‰ด์Šค ๊ฒ€์ƒ‰ ๊ฐœ์š” ๊ฐœ์š” ๊ฒ€์ƒ‰ API์™€ ๋‰ด์Šค ๊ฒ€์ƒ‰ ๊ฐœ์š” ๊ฒ€์ƒ‰ API๋Š” ๋„ค์ด๋ฒ„ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋‰ด์Šค, ๋ฐฑ๊ณผ์‚ฌ์ „, ๋ธ”๋กœ๊ทธ, ์‡ผํ•‘, ์›น ๋ฌธ์„œ, ์ „๋ฌธ์ •๋ณด, ์ง€์‹iN, ์ฑ…, ์นดํŽ˜๊ธ€ ๋“ฑ ๋ถ„์•ผ๋ณ„๋กœ ๋ณผ ์ˆ˜ ์žˆ๋Š” API์ž…๋‹ˆ๋‹ค

developers.naver.com

 

 

 

 

vscode ์ž‘์„ฑํ•˜๊ธฐ

 

 

 

 

๋จผ์ €, vscode ํ„ฐ๋ฏธ๋„ cmd ์ฐฝ์—์„œ requests๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

pip install requests

 

 

 

 

requirements.txt ํŒŒ์ผ์— ๋„ฃ์–ด์ค€๋‹ค.

 

 

 

 

 

config.py ํŒŒ์ผ์„ ์ž‘์„ฑํ•œ๋‹ค.

 

 

 

์ด ์•ˆ์—, ๋„ค์ด๋ฒ„ API ํ‚ค ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค.

 

 

 

 

๋„ค์ด๋ฒ„ API ํ‚ค ๊ฐ’์€,

 

https://developers.naver.com/main/

 

NAVER Developers

๋„ค์ด๋ฒ„ ์˜คํ”ˆ API๋“ค์„ ํ™œ์šฉํ•ด ๊ฐœ๋ฐœ์ž๋“ค์ด ๋‹ค์–‘ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก API ๊ฐ€์ด๋“œ์™€ SDK๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ณต์ค‘์ธ ์˜คํ”ˆ API์—๋Š” ๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ, ๊ฒ€์ƒ‰, ๋‹จ์ถ•URL, ์บก์ฐจ๋ฅผ ๋น„๋กฏ ๊ธฐ๊ณ„๋ฒˆ์—ญ, ์Œ

developers.naver.com

 

 

์ด๊ณณ์—์„œ ํšŒ์›๊ฐ€์ž… ํ•œ ํ›„, Application ์—์„œ ๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ•˜๋ฉด,

 

 

 

์ด๊ณณ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

app.py๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

import serverless_wsgi
from flask import Flask
from flask_restful import Api

from resources.news import NewSearchResource

app = Flask(__name__)
api = Api(app)

api.add_resource( NewSearchResource , '/news/search')

def handler(event, context) :
    return serverless_wsgi.handle_request(app, event, context)

if __name__ == '__main__':
    app.run()

 

 

 

 

resources ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ , news.py๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

from flask import request
from flask_restful import Resource

# API ์š”์ฒญ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
import requests

# ๋‚ด๊ฐ€ ๋งŒ๋“  ๋ณด์•ˆ ๊ฐ’ class
from config import Config

class NewSearchResource(Resource) :
    def get(self) :
		
        # params ์— ์ฟผ๋ฆฌ ๊ฐ’์ด ์—†์œผ๋ฉด ๋ฆฌํ„ด
        if 'query' not in request.args :
            return {"result":"fail", "error":"๊ฒ€์ƒ‰์–ด๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค."}, 400
        
        # params์— ์žˆ๋˜ ๊ฐ’ ๋ณ€์ˆ˜๋กœ ์ €์žฅ (๋”•์…”๋„ˆ๋ฆฌ์—ฌ์„œ .get() ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.)
        keyword = request.args.get('query')

        # ๋„ค์ด๋ฒ„ API ํ˜ธ์ถœํ•œ๋‹ค.
        # API ํ˜ธ์ถœํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ requests
        
        # ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ GET, POST, PUT, DELETE API๋ฅผ
        # ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ requests ๋‹ค.
		
        # openAPI ์—์„œ ์ œ๊ณตํ•˜๋Š” url, params
        # params ์•ˆ์—๋Š” ๋‚ด๊ฐ€ ์„ค์ •ํ•œ ๊ฐ’ + ์˜ต์…˜๋“ค
        # openAPI ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ด๋”” ๊ฐ’ ๊ณผ ์‹œํฌ๋ฆฟ ๊ฐ’ ์ž…๋ ฅ
        url = 'https://openapi.naver.com/v1/search/news.json'
        params = {'query' : keyword,
                  'display' : 30,
                  'sort' : 'date'}
        headers = {'X-Naver-Client-Id' : Config.X_NAVER_CLIENT_ID,
                   'X-Naver-Client-Secret' : Config.X_NAVER_CLIENT_SECRET}
		
        # ๊ฐ’์„ requests์˜ get()ํ•จ์ˆ˜ ์‚ฌ์šฉํ•ด์„œ ๋ฐ›์•„์ฃผ๊ธฐ
        response = requests.get( url, params= params, headers= headers)
        
        # ์‘๋‹ต์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ๋ฐ›๋Š”๋‹ค.
        # ํฌ์ŠคํŠธ๋งจ ์‘๋‹ต ๋ฐ”๋””์— JSON์œผ๋กœ ๋˜์–ด์žˆ์–ด์„œ ๊ฐ€๋Šฅํ•˜๋‹ค.
        response = response.json()
        print( response )

        return {"result" : "success", 
                "items" : response['items'], 
                "count" : len(response['items'])}

 

 

 

 

 

์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋œฌ๋‹ค๋ฉด,

 

 

 

๋„์ปค๋ฅผ ์‹คํ–‰ํ•œ ์ฑ„๋กœ sls deploy๋ฅผ ํ•˜๋„๋ก ํ•˜์ž.

 

 

 

 

 

Postman

 

 

Params ๋ถ€๋ถ„์„ ์ž‘์„ฑํ•ด์ฃผ๊ณ ,

 

 

 

 

 

ํ—ค๋” ๋ถ€๋ถ„์— ํ‚ค ๊ฐ’์„ ์ž…๋ ฅํ•ด์ค€๋‹ค

 

 

 

 

 

๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ( cmd์— flask run ๋ช…๋ น์–ด ์‹คํ–‰)๋Š” ์ด๋ ‡๊ฒŒ ๋œฌ๋‹ค.

 

 

 

 

vscode์— sls deploy์‹œ์—, ๊ฒฐ๊ณผ๊ฐ’์€ ์ด๋ ‡๊ฒŒ ๋œฌ๋‹ค

 

 

 

 

 

๊นƒํ—ˆ๋ธŒ ์•ก์…˜์ฆˆ์—์„œ๋„ ๊ตฌ๋™๋˜๋Š”์ง€ ํ™•์ธํ•˜์ž.