사전 웹 프레임워크
개념

웹 프레임워크

gabury1고친 사람 github-actions[bot]

웹 프레임워크는 웹 서비스를 만들 때 매번 되풀이되는 일을 대신 맡아 줍니다. 요청을 받아 알맞은 코드에 넘깁니다. 그 코드가 낸 결과는 응답으로 바꿔 돌려보냅니다. 개발자는 그 틀 안에 자기 서비스에만 있는 규칙을 채워 넣습니다.

쉽고 빠른 이해

웹 프레임워크는 웹 서비스의 뼈대를 미리 짜 두고 개발자의 코드를 그 안에 끼워 쓰게 합니다. 게시판을 만든다면 개발자는 「7번 글을 읽어 온다」는 함수만 씁니다. 그 함수를 언제 부를지는 프레임워크가 정합니다.

웹 요청은 정해진 형식의 텍스트로 들어옵니다. 프레임워크가 없으면 그 텍스트를 쪼개는 코드와 주소마다 갈 함수를 고르는 코드를 서비스마다 다시 짜야 합니다. 그러다 보면 보안 구멍도 쉽게 생깁니다.

  1. 서버가 받은 요청을 넘겨받아 공통 검사를 거칩니다
  2. 주소를 보고 그 요청을 맡을 함수를 골라 부릅니다
  3. 함수가 돌려준 값을 응답으로 바꿔 보냅니다

대가는 프레임워크가 정한 방식을 따라야 한다는 것입니다. 그 방식 밖의 일은 오히려 어렵습니다. 내 함수를 부르는 쪽이 프레임워크라서 문제가 나면 프레임워크 코드까지 읽어야 합니다. 주소 한두 개짜리 작은 도구처럼 되풀이되는 일이 적으면 대가만 남습니다.

상세

공연장은 무대와 조명과 객석 안내를 미리 갖춰 둡니다. 극단은 대본과 배우만 데리고 옵니다. 막을 언제 올리고 언제 내릴지는 공연장이 정합니다.

비유의 공연장이 웹 프레임워크입니다. 극단의 대본은 개발자가 쓰는 코드입니다.

웹 프레임워크는 웹 요청을 받아 응답을 돌려주기까지 되풀이되는 일을 미리 짜 둔 코드 묶음입니다. 게시판이라면 「7번 글을 보여 달라」는 요청을 받는 일, 7 이라는 값을 꺼내는 일, 결과를 돌려보내는 일이 그렇습니다. 개발자가 쓰는 것은 「7번 글을 읽어 온다」는 부분뿐입니다.

이 글의 웹 프레임워크는 서버에서 도는 쪽입니다. 브라우저에서 화면을 짜는 도구도 웹 프레임워크라 불릴 때가 있습니다. 그쪽은 흔히 프론트엔드 프레임워크라고 갈라 부릅니다.

요청과 응답

웹 프레임워크가 다루는 재료는 요청과 응답입니다. 브라우저와 서버는 HTTP(HyperText Transfer Protocol)라는 약속으로 말을 주고받습니다. 브라우저가 보내는 말을 요청, 서버가 돌려주는 말을 응답이라고 합니다. 둘 다 정해진 형식으로 적힌 텍스트입니다.

요청의 첫 줄에는 무엇을 할지와 어느 주소인지가 적힙니다. GET /posts/7 은 「7번 글을 달라」는 뜻입니다. 그 아래에 부가 정보를 적는 헤더와 본문이 따라옵니다.

서버 쪽에서는 누군가 이 텍스트를 쪼개 뜻을 읽어야 합니다. 응답도 같은 형식으로 적어 돌려보내야 합니다. 이 일은 서비스가 게시판이든 쇼핑몰이든 똑같습니다.

프레임워크 없이 짜면 생기는 일

웹 프레임워크가 왜 필요한지는 없을 때를 보면 드러납니다. 그때 생기는 곤란은 셋입니다.

첫째는 같은 코드를 서비스마다 다시 쓰는 것입니다. 요청 텍스트를 쪼개는 코드, 주소를 보고 갈 함수를 고르는 코드, 응답을 형식에 맞게 적는 코드가 그렇습니다. 서비스의 규칙과 무관한 코드가 서비스 코드보다 길어집니다.

둘째는 보안 구멍입니다. 사용자가 보낸 글을 손대지 않고 화면에 내보내면 그 글에 숨긴 스크립트가 남의 브라우저에서 돕니다. 이것이 크로스 사이트 스크립팅입니다. 많은 웹 프레임워크가 이런 구멍을 막는 장치를 처음부터 켜 둡니다.

셋째는 사람마다 구조가 갈리는 것입니다. 프레임워크는 파일을 어디에 두고 함수를 어떻게 잇는지 정해 줍니다. 그래서 새로 온 사람도 어디를 열어 볼지 압니다.

라이브러리와 다른 점

웹 프레임워크를 라이브러리와 가르는 기준은 누가 누구를 부르느냐입니다. 라이브러리는 내 코드가 필요할 때 불러 씁니다. 프레임워크는 거꾸로 내 코드를 부릅니다.

이렇게 흐름을 쥔 쪽이 내 코드에서 프레임워크로 넘어가는 것을 제어 역전이라고 합니다. 공연장에서 막을 올리는 쪽이 극단이 아니라 공연장인 것과 같습니다.

코드로 보면 이렇습니다. 아래는 흔한 형식을 줄여 적은 것입니다. 특정 제품의 문법은 아닙니다.

Python
def show_post(request, post_id):
    post = load_post(post_id)
    return render("post", post)

route("/posts/{id}", show_post)

개발자가 하는 일은 둘뿐입니다. 함수를 씁니다. 그 함수를 주소에 이어 둡니다. show_post 를 부르는 줄은 개발자 코드 어디에도 없습니다.

GET /posts/7 이 들어오면 프레임워크가 post_id 에 7 을 넣어 show_post 를 부릅니다. 함수 안의 render 는 값을 웹 페이지 화면으로 바꿔 주는 프레임워크 함수입니다. "post" 는 그때 쓸 화면 틀의 이름입니다.

요청 하나가 지나가는 길

요청은 프레임워크에 곧장 닿지 않습니다. 네트워크 연결을 받는 일은 대개 앞에 선 웹 서버가 맡습니다. 웹 서버가 요청을 건네면 그때부터 프레임워크 차례입니다.

프레임워크 안에서 GET /posts/7 요청 하나는 부품 셋을 차례로 지납니다. 미들웨어, 라우팅, 핸들러 순서입니다.

미들웨어는 모든 요청이 공통으로 거치는 검사대입니다. 로그인했는지 보거나 요청을 기록하는 일을 맡습니다. 함수 수십 개에 같은 검사를 넣는 대신 한 곳에 둡니다.

라우팅은 주소를 보고 어느 함수가 요청을 맡을지 고르는 일입니다. /posts/7 은 /posts/{id} 패턴과 맞으니 show_post 로 갑니다. 이때 주소에서 7 을 꺼내 함수에 넘깁니다.

핸들러는 요청 하나를 맡아 처리하는 개발자의 함수입니다. 앞 코드의 show_post 가 핸들러입니다. 프레임워크에 따라 뷰나 컨트롤러라고도 부릅니다.

웹 서버까지 넣어 한 그림으로 이으면 이렇습니다. 응답도 들어온 길을 거슬러 미들웨어와 웹 서버를 지나 나갑니다.

sequenceDiagram
    participant 브라우저
    participant 웹 서버
    participant 미들웨어
    participant 라우팅
    participant 핸들러
    브라우저->>웹 서버: GET /posts/7
    웹 서버->>미들웨어: 요청을 건넨다
    Note over 미들웨어: 로그인했는지 본다
    미들웨어->>라우팅: 통과
    Note over 라우팅: /posts/{id} 패턴과 맞는다
    라우팅->>핸들러: show_post 를 부르며 7 을 넘긴다
    핸들러-->>미들웨어: 7번 글
    미들웨어-->>웹 서버: 응답
    웹 서버-->>브라우저: 응답

핸들러가 돌려준 값은 프레임워크가 응답으로 바꿉니다. 화면을 돌려주는 서비스는 HTML(HyperText Markup Language) 문서로 적습니다. 다른 프로그램이 불러 쓰는 API(Application Programming Interface)는 대개 JSON(JavaScript Object Notation)으로 적습니다.

프레임워크가 함께 갖춘 도구

요청과 응답을 잇는 일 말고도 웹 서비스마다 되풀이되는 일이 더 있습니다. 많은 프레임워크가 그 도구를 기본으로 갖추고 있습니다.

도구 하는 일 없으면
템플릿 엔진 HTML 틀에 값을 끼워 화면을 만든다 문자열을 이어 붙여 HTML 을 짓는다
ORM(Object-Relational Mapping, 객체-관계 매핑) 데이터베이스의 표를 코드의 객체로 다룬다 질의문을 손으로 짓는다
세션 요청과 요청 사이에 같은 사용자를 알아본다 로그인 상태를 직접 기억해야 한다
입력 검증 들어온 값이 맞는 형식인지 본다 값마다 검사 코드를 쓴다
위조 요청 방어 다른 사이트가 몰래 보낸 요청을 걸러낸다 요청마다 출처를 직접 따진다

표의 마지막 줄이 막는 공격이 크로스 사이트 요청 위조입니다. 사용자가 로그인한 채 다른 사이트를 열었을 때 그 사이트가 사용자 몰래 내 서비스로 요청을 보내는 공격입니다.

풀스택 프레임워크와 마이크로 프레임워크

웹 프레임워크는 앞 표의 도구를 얼마나 갖췄느냐로 둘로 갈립니다.

풀스택 프레임워크는 앞 표의 도구를 거의 다 기본으로 갖춥니다. 고를 것이 적고, 프레임워크가 미리 정해 둔 방식이 많습니다. Django 와 Rails 가 흔히 이쪽으로 꼽힙니다.

마이크로 프레임워크는 라우팅과 요청·응답 처리만 갖춥니다. 데이터베이스 도구나 템플릿 엔진은 개발자가 골라 붙입니다. 흔히 꼽는 예는 Flask 와 Express 입니다.

둘은 고르는 일을 누가 지느냐가 다릅니다. 풀스택은 프레임워크가 골라 두었으니 바꾸기가 어렵습니다. 마이크로는 바꾸기 쉬운 대신 고르고 잇는 일이 개발자 몫입니다.

대가

웹 프레임워크를 쓰면 내주는 것이 넷입니다. 앞에서 본 장점이 곧 대가의 뿌리입니다.

첫째, 프레임워크가 그려 둔 흐름을 따라야 합니다. 요청 하나를 받아 응답 하나를 돌려주는 흐름에 안 맞는 일은 그 흐름을 거슬러 짜야 합니다. 연결을 오래 붙들고 서버가 먼저 사용자에게 알림을 보내는 일이 그런 예입니다.

둘째, 흐름이 내 코드에 안 보입니다. 내 함수를 부르는 쪽이 프레임워크라서 호출 순서가 내 코드에 적혀 있지 않습니다. 오류가 나면 프레임워크 코드까지 따라 읽어야 할 때가 있습니다.

셋째, 다른 프레임워크로 옮기기 어렵습니다. 핸들러와 설정이 전부 그 프레임워크의 방식으로 적히기 때문입니다. 프레임워크가 새 버전을 내면 내 코드도 따라 고쳐야 합니다.

넷째, 거치는 단계가 늡니다. 요청 하나가 미들웨어와 라우팅을 지나며 일이 덧붙습니다. 주소 하나에 늘 같은 내용만 돌려주는 요청이라면 직접 짠 코드보다 할 일이 많습니다.

언제 쓰고 언제 안 쓰나

고르는 기준은 되풀이되는 일이 얼마나 많으냐입니다. 흔한 상황 넷을 견주면 이렇습니다.

상황 흔히 고르는 것 까닭
화면과 로그인과 데이터베이스가 다 있는 서비스 풀스택 프레임워크 갖춘 도구를 거의 다 쓴다
다른 프로그램에 JSON 만 돌려주는 서버 마이크로 프레임워크 화면 도구가 필요 없다
주소 한두 개만 받는 작은 내부 도구 마이크로 프레임워크나 언어에 딸린 HTTP 서버 되풀이되는 일이 적다
요청 하나에 함수 하나만 도는 서버리스 환경 프레임워크 없이 함수만 쓰기도 한다 라우팅을 플랫폼이 맡는다

표에서 보듯 아래로 갈수록 프레임워크가 덜어 줄 일이 줄어듭니다. 덜어 줄 일이 적으면 위의 대가만 남습니다.

관련 항목

웹 프레임워크를 이루는 구성 요소

라우팅 · 미들웨어 · 핸들러 · 뷰 · 컨트롤러 · 템플릿 엔진 · ORM · 세션 · 입력 검증

웹 프레임워크를 짓는 설계 원칙

제어 역전 · 의존성 주입 · MVC · MTV · 설정보다 관례

웹 프레임워크가 주고받는 규약과 형식

HTTP · HTTP 요청 · HTTP 응답 · 요청 메서드 · HTML · JSON · REST · API

웹 프레임워크 앞에 서는 서버

웹 서버 · 애플리케이션 서버 · 리버스 프록시 · WSGI · ASGI

웹 프레임워크가 기본으로 막는 공격

크로스 사이트 스크립팅 · 크로스 사이트 요청 위조 · SQL 인젝션 · 클릭재킹

웹 프레임워크를 구현한 제품

Django · Rails · Flask · FastAPI · Express · Spring Boot · Laravel · Symfony

웹 프레임워크와 맞세워지는 개념

라이브러리 · 프레임워크 · 프론트엔드 프레임워크 · 풀스택 프레임워크 · 마이크로 프레임워크 · 서버리스

웹 프레임워크가 속하는 상위 분류

백엔드 · 웹 개발 · 서버 · 웹 애플리케이션

다른 이름: web framework · 웹 애플리케이션 프레임워크 · web application framework