API에 관하여

공부를 하다가 생각난게 있다. API란 무엇인가. Flask를 사용해 웹을 공부하다보면 데이코레이션이라든지 미들웨어라든지 여러가지 정보를 배우는데 API에 대해 공부해보면 사실상 내가 배우는 거랑 무슨 차이인가 싶다. 이것에 대한 답을 이곳에 적고자 한다.

- 해당 포스트의 최근 업데이트 (2024-05-11)


1964년 api는 처음 하드웨어 독립성을 높이기 위해서 사용되었는데 예를 들어서 서로다른 하드웨어 부품마다 개발자가 하나하나 프로그램을 새롭게 작성하는것 보다 같은 일을 하는 하드웨어를 추상화 시켜 함수를 한번 사용하여 서로다른 화면에 출력하는 일을 쉽게 사용해주기 위해 생겨난 개념이다. 라고 알려져있는데 그다지 와 닿지 않는다.

내가 생각하는 API는 정확히 정보를 주고 받는 것에 중점을 둔 기능 중 하나이다. API와 일반적인 웹 개발 코드들도 웹 애플리케이션을 개발하고, HTTP를 통해 요청과 응답을 처리하고, 사용자에게 인터페이스를 제공하는 공통된 점이 있다.

한 번 비교를 해보자.

아래의 코드는 그냥 간단하게 예제를 위한 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
# API 사용 X

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello Flask!"

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

이 코드를 보면 Flask를 이용했거나 백엔드를 조금이라도 공부했다면 이 코드가 어디에 쓰이는지 짐작할 수 있을 것이다.

하지만 이 코드만 일방적으로 보여주기만 하는 코드이다. 설명하려면 좀 더 코드가 필요할 것 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from flask import Flask, request, render_template
import sqlite3

app = Flask(__name__)

conn = sqlite3.connect('sample.db', check_same_thread=False)
cur = conn.cursor()

cur.execute('''CREATE TABLE IF NOT EXISTS users
              (id INTEGER PRIMARY KEY, username TEXT, email TEXT)''')
conn.commit()

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        username = request.form['username']
        email = request.form['email']
        
        cur.execute("INSERT INTO users (username, email) VALUES (?, ?)", (username, email))
        conn.commit()

    cur.execute("SELECT * FROM users")
    users = cur.fetchall()
    
    return render_template('index.html', users=users)

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

이제 좀 봐줄 만 해졌다. 위의 코드는 대충 사용자가 입력한 정보를 토대로 DB에 저장한 코드이다. 추가된 것은 간단한 SQL문 정도 추가 되었는데, 자 이제 사용자와 상호작용까지한다. 하지만 그럼에도 이건 API를 사용하지 않았다.

이번에는 API를 사용해 보겠다. 다음은 API를 구현한 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# API 사용 O

from flask import Flask
from flask_restx import Api, Resource, fields
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sample.db'  
db = SQLAlchemy(app)

api = Api(app, 
          version='1.0', 
          title='Login API', 
          description='A simple login API')

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(50), nullable=False)

with app.app_context():
    db.create_all()

login_model = api.model('Login', {
    'username': fields.String(required=True, description='사용자명', example="cl_victor"),
    'password': fields.String(required=True, description='비밀번호', example="1234")
})

@ns.route('/login')
class Login(Resource):
    @api.expect(login_model)  
    def post(self):
        data = api.payload
        username = data.get('username')
        password = data.get('password')

        new_user = User(username=username, password=password)
        db.session.add(new_user)
        db.session.commit()

        return {"message": "사용자가 추가되었습니다."}, 201

    def get(self):
        users = User.query.all()
        user_list = [{"id": user.id, "username": user.username, "password": user.password} for user in users]
        return {"users": user_list}, 200

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

이번의 코드는 API를 이용해 만들어봤다. 뭐 들어간게 매우 많은데 궁금한 건 좀 더 검색해보는 것을 추천한다. 일단 필자가 알고 있기 때문에 대충 넘어갈 것이다.

아까 전 코드와 이 코드의 공통점은

  1. URL 라우팅을 통해 클라이언트 요청을 처리해준다.
  2. HTTP 메서드(여기엔 안 나온 GET, POST, PUT, DELETE 등)를 사용한다. 클라이언트의 요청을 서버로 전달하고, 서버가 이에 따라 적절한 응답을 반환해준다.
  3. 데이터 처리를 한다.

왜 공통점을 먼저 알려주는지 이상하게 느낄 수 있다. 사실 API의 유무는 데이터 처리 하나 때문에 갈리는 거라고 생각한다. 아닌 것 같다고 생각되면 글 좀 알려주세요.

일단 API를 사용하지 않은 코드는 애플리케이션의 벡엔드 엔드포인트를 처리하고 사용자와 상호작용에 중점을 두고 있고, API는 데이터를 주고받는데 주로 사용된다.

이게 끝? 그렇다. 진짜 별 거 없다.

그러면 API 왜 쓰냐? 그건 RedHat 공식 홈페이지에 잘 나와있다.

아래는 그냥 추가적인 정보다.

API란

정의 및 프로토콜 집합을 사용하여 두 소프트웨어 구성 요소가 서로 통신할 수 있게 하는 메커니즘

More info API는 여러 프로그램들과 데이터베이스, 그리고 기능들의 상호 통신 방법을 규정하고 도와주는 매개체
**API(Application Programming Interface)** API의 맥락에서 애플리케이션이라는 단어는 고유한 기능을 가진 모든 소프트웨어를 나타냅니다. 인터페이스는 두 애플리케이션 간의 서비스 계약이라고 할 수 있습니다. 이 계약은 요청과 응답을 사용하여 두 애플리케이션이 서로 통신하는 방법을 정의합니다. API 문서에는 개발자가 이러한 요청과 응답을 구성하는 방법에 대한 정보가 들어 있습니다.

**Web의 진화와 API** API의 필요성은 Web의 진화와 밀접한 연관이 있으니 잠깐 살펴보면, 모놀리틱 아키텍처(Monolithic Architecture)가 주도적이었던 Web 1.0 시대에서는 (하지만 현재에도 사실 많이 쓰이고 있는 것이 사실!) 서버와 클라이언트가 분리되지 않고 모두 서버에서 동시에 처리하기 때문에 API 필요성이 그다지 절실하지 않았다.

그러나 2000년경부터 시작된 Web2.0의 “개방, 참여, 공유”의 정신을 바탕으로 정보가 쌍방향으로 소통하고 “사용자가 생성한 데이터”를 위주로 웹 앱의 붐, 그리고 2010년대 들어서 클라우드(Cloud) 기반 인프라와 MSA(Microservices Architecture)의 사용이 확산되면서 API 확산이 가속화되었고 이제 API에서 가장 흔한 구조인 REST 또는 RESTful API가 점차 새로운 웹 생태계의 기반으로 주목된 것이다.



API 작동 방식

API 아키텍처는 일반적으로 클라이언트와 서버 측면에서 설명됩니다. 요청을 보내는 애플리케이션을 클라이언트라고 하고 응답을 보내는 애플리케이션을 서버라고 합니다. 따라서 날씨 예에서 기상청의 날씨 데이터베이스는 서버이고 모바일 앱은 클라이언트입니다.

API 작동 방식을 이해하는 간단한 방법은 일반적인 예인 제3자 결제 방식을 살펴보는 것입니다. 사용자가 전자상거래 사이트에서 제품을 구매할 때 'Paypal로 결제' 또는 다른 유형의 타사 시스템을 사용하라는 메시지가 표시될 수 있습니다. 이 기능은 API를 사용하여 연결합니다.

구매자가 결제 버튼을 클릭하면 API가 호출하여 정보를 가져올 수 있으며 이를 요청이라고도 합니다. 이 요청은 API의 URI(Uniform Resource Identifier)를 통해 애플리케이션에서 웹 서버로 처리되며 요청 동사, 헤더 및 때로는 요청 본문이 포함되기도 합니다.

API는 제품 웹페이지로부터 유효한 요청을 받은 후 외부 소프트웨어 또는 웹서버, 이 경우에는 제3자 결제 시스템으로 호출합니다.

- 서버는 요청된 정보와 함께 API에 응답을 보냅니다. API는 데이터를 초기 요청 애플리케이션(여기서는 제품 웹사이트)으로 전송합니다. 데이터 전송은 사용 중인 웹 서비스에 따라 다르지만 요청 및 응답은 모두 API를 통해 발생합니다. 사용자 인터페이스에는 가시성이 없으므로 API는 컴퓨터 또는 애플리케이션 내에서 데이터를 교환하며 사용자에게 원활한 연결로 나타납니다.

API의 종류

접근 방식에 따른 유형

private API

내부 API로, 기업이나 연구 단체 등에서 자체 제품과 운영 개선을 위해 단체 내부에서만 사용. 따라서 제삼자에게 노출 X

Public API

개방형 API로, 모두에게 공개. ublic API 중에서도 접속하는 대상에 대한 제약이 없는 경우를 OpenAPI

Partner API

Partner API는 특정 비즈니스 파트너 간의 데이터 공유. 그러므로 동의하는 특정인들만 사용할 수 있다.


오픈 API 사이트 예:

구글  공공데이터포털  문화데이터 광장   카카오 


아키텍처 스타일에 따른 API 종류

SOAP, RPC, REST API, 그리고 GraphQL

각각 유형과 기능, 보완 지원방식 등에 차이점이 있지만 이 글에서는 깊이 들어가지 않겠다. 지금 2022년 시점에서는 이중 REST/RESTful API와 GraphQL를 더욱 살펴보기를 권장하고, 이글에서는 현재 사실상 표준화가 되었다 해도 과언이 아닐 정도로 가장 많이 쓰이고 있는 REST* API를 중점으로 쓴다.



SOAP API

이 API는 단순 객체 접근 프로토콜을 사용합니다. 클라이언트와 서버는 XML을 사용하여 메시지를 교환합니다. 과거에 더 많이 사용되었으며 유연성이 떨어지는 API입니다.

RPC API

이 API를 원격 프로시저 호출이라고 합니다. 클라이언트가 서버에서 함수나 프로시저를 완료하면 서버가 출력을 클라이언트로 다시 전송합니다.

Websocket API

Websocket API는 JSON 객체를 사용하여 데이터를 전달하는 또 다른 최신 웹 API 개발입니다. WebSocket API는 클라이언트 앱과 서버 간의 양방향 통신을 지원합니다. 서버가 연결된 클라이언트에 콜백 메시지를 전송할 수 있어 REST API보다 효율적입니다.

REST API

오늘날 웹에서 볼 수 있는 가장 많이 사용되고 유연한 API입니다. 클라이언트가 서버에 요청을 데이터로 전송합니다. 서버가 이 클라이언트 입력을 사용하여 내부 함수를 시작하고 출력 데이터를 다시 클라이언트에 반환합니다. 아래에서 REST API에 대해 더 자세히 살펴보겠습니다.

GraphQL

GraphQL은 Facebook에서 나온 기술이나 현재는 오픈소스이다. 데이터 질의 (Query + Schema) 언어, 클라이언트는 GraphQL 서버로 쿼리를 전송하고, 서버는 해당 쿼리를 해석하고 데이터를 반환한다.

이 때, 클라이언트가 요청한 필드만 반환되므로 over fetching을 줄여 효율적이다. 또한, GraphQL은 스키마를 사용하여 데이터 모델을 정의하기 때문에 클라이언트와 서버 간의 일관성 있는 데이터 통신을 보장한다. 이를 통해 클라이언트가 서버가 제공하는 데이터 중 원하는 데이터를 가져오는 것이 가능하다.

SQL이 데이터베이스 시스템으로부터 데이터를 가져오는 목적을 가진다면,GraphQL은 클라이언트가 데이터를 서버로부터 가져오는 것을 목적으로 한다.

gRPC

gRPC는 구글(Google)에서 시작한 오픈소스이며, ‘원격 프로시저 호출(RPC, Remote Procedure Calls)’을 위한 시스템입니다. 쉽게 풀어서 쓰면, A 서버(gRPC 서버)에서 만들어 둔 함수를 B 서버(gRPC 클라이언트)가 사용할 수 있습니다. 양단에서 모두 함수를 제공·이용할 수 있도록 통신 인터페이스를 작성하여 양단에 미리 제공합니다.

나중에 정리해야 할 듯하다. 너무나도 방대한 내용이다.



API의 장단점

API의 장점

  • 데이터 접속의 표준화와 편의성 :

조직에서 애플리케이션을 개발할 때 기능적 API를 사용하면, 필요한 기본 기능들– 인증, 통신, 지불 처리 및 위치 확인 등–을 매번 자가 개발/업데이트할 필요 없이 손쉽게 이용 가능

  • 자동화와 확장성 :

API를 통한 CRUD 처리에 따라 관련 데이터와 콘텐츠가 자동으로 생성되고 사용자의 환경에 맞춰서 정보가 전달 되어 개발 워크플로우가 간소화되고 애플리케이션 확장이 다소 용이

  • 적용력 :

API는 변화 예측에도 큰 도움이 되기 때문에 API를 통해 데이터를 수집하고 전달하는 데 있어 유연한 서비스 환경을 구축하고 소프트 웨어를 통합하고자 할 때, 그리고 개발자들 간의 협업이 필요할 때 더욱 용이

API의 단점

  • 보안성과 HTTP 방식의 제한

가장 주목할 것은 API의 단일 진입점인 API 게이트웨이는 해커의 타겟 대상이 될 수 있다는 점이다. 한마디로 API의 장점– 평범한 HTTP 메서드를 사용하여 액세스 할 수 있다는 점–이, 보안성에 관해서는 반면 크나큰 단점이 된다.

이 때문에 다른 일반적 인터넷 기반 리소스와 마찬가지로 메시지 가로채기 공격(man-in-the-middle), CSRF(Cross-Site Request Forgery) 공격, 크로스 사이트 스크립팅(Cross Site Scripting, XSS), SQL 삽입 공격(SQL injection), DDoS(Denial-of-service attack) 공격 (서비스 거부 공격) 등에 취약한 것이 사실이다. 또한 이러한 HTTP method는 메서드 형태가 다소 제한적이라는 문제점이 있다. API 보안

  • 표준의 부재와 개발 비용

REST API의 설계에 있어 가장 큰 단점이라고 할 수 있는 점이 공식화된 표준이 존재하지 않는다는 점이다. 그러므로 관리가 어렵고 실제로 API 기능을 구현하고 제공하려면 개발 시간, 지속적인 유지 관리 요구 사항 및 지원 제공 측면에서 비용이 많이 들 수 있다. 또한 기존 API의 기능을 확장하려고 할 때 광범위한 프로그래밍 지식이 필요하다.






referrence : Amazon  hanl.tech  redHat