본문 바로가기

주소 하나에 함수 하나

1. 이번 절의 목표

백엔드의 뼈대는 "주소 하나에 함수 하나"입니다. 이것만 알면 어떤 백엔드 코드를 봐도 절반은 읽힙니다.

1교시에 만든 서버는 주소가 / 하나뿐입니다. 이번 절에서는 주소를 늘려 갑니다. 만들 주소를 먼저 표로 적습니다. 실제 개발도 이렇게 주소 목록부터 적고 시작합니다.

주소화면에 나올 것
/hello world
/aboutabout 입니다
/notice게시판 입니다
/notice/11번 게시물 입니다
/notice/22번 게시물 입니다
/notice/33번 게시물 입니다

2. 여덟 줄 다시 읽기

1교시 코드를 다시 봅니다.

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()


@app.get("/", response_class=HTMLResponse)
def index():
    return "<h1>hello world</h1>"
  • 1~2번째 줄: FastAPI라는 도구 상자에서 필요한 것 두 개를 꺼냅니다. import는 "가져오기"입니다.
  • 4번째 줄: 서버 한 대를 만들어 app이라는 이름을 붙입니다.
  • 7번째 줄: "아래 함수는 / 주소에 붙인다"는 스티커입니다. @로 시작하는 줄은 바로 아래 함수에 붙는 스티커라고 생각하면 됩니다.
  • 8~9번째 줄: 함수입니다. 브라우저가 /를 달라고 하면 이 함수가 실행되고, return 뒤의 글자가 브라우저로 갑니다.

response_class=HTMLResponse는 "돌려주는 글자를 HTML로 취급해 달라"는 뜻입니다. 이게 없으면 브라우저가 <h1>을 큰 글씨로 그리지 않고 글자 그대로 보여 줍니다.

파이썬 다시 보기: 데코레이터

@app.get("/")처럼 @로 시작하는 줄을 데코레이터라고 부릅니다. 원리는 이 책에서 다루지 않습니다. "바로 아래 함수에 주소를 붙이는 스티커"로만 기억하면 이 책에서는 충분합니다. 스티커와 함수는 항상 붙어 다니고, 그 사이에 빈 줄을 넣지 않습니다.

3. 주소 늘리기

main.py를 아래처럼 바꿉니다. 서버는 켜 둔 채로 저장하면 알아서 다시 켜집니다.

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()


@app.get("/", response_class=HTMLResponse)
def index():
    return "<h1>hello world</h1>"


@app.get("/about", response_class=HTMLResponse)
def about():
    return "<h1>about 입니다</h1>"


@app.get("/notice", response_class=HTMLResponse)
def notice():
    return "<h1>게시판 입니다</h1>"

브라우저에서 세 주소를 차례로 쳐 봅니다.

http://127.0.0.1:8000/
http://127.0.0.1:8000/about
http://127.0.0.1:8000/notice

주소가 바뀔 때마다 다른 함수가 실행되고 다른 글자가 나옵니다. 없는 주소, 예를 들어 /contact를 치면 {"detail":"Not Found"}가 나옵니다. 그 주소에 붙은 함수가 없다는 뜻입니다.

서버가 주소를 받았을 때 하는 판단은 하나뿐입니다. 이 주소에 붙은 함수가 있는가.

4. 게시물 세 개를 하드코딩으로

이제 게시물 1, 2, 3번을 만듭니다. 방법을 아직 모르니 아는 방식 그대로, 주소 하나에 함수 하나로 씁니다. 아래를 main.py 맨 아래에 이어서 씁니다.

@app.get("/notice/1", response_class=HTMLResponse)
def notice_1():
    return "<h1>1번 게시물 입니다</h1>"


@app.get("/notice/2", response_class=HTMLResponse)
def notice_2():
    return "<h1>2번 게시물 입니다</h1>"


@app.get("/notice/3", response_class=HTMLResponse)
def notice_3():
    return "<h1>3번 게시물 입니다</h1>"

/notice/1, /notice/2, /notice/3을 쳐 보면 각각 나옵니다. 동작합니다. 표에 적은 주소 여섯 개가 전부 됩니다.

이렇게 값을 코드에 직접 써 넣는 것을 하드코딩이라고 합니다. 처음에는 이게 가장 이해하기 쉽습니다. 문제는 게시물이 100개면 함수를 100개 써야 한다는 것입니다. 이 불편함이 다음 절의 출발점입니다.

5. 함수 이름 이야기

세 함수의 이름을 전부 notice로 써도 서버는 돌아갑니다. 스티커가 붙는 순간 주소와 함수가 연결되기 때문에, 이름이 겹쳐도 FastAPI는 신경 쓰지 않습니다. 하지만 사람이 읽을 때는 헷갈리므로 이 책에서는 이름을 다르게 씁니다. 왜 겹쳐도 되는지 궁금하면 아래 프롬프트로 물어보세요.

AI에게 물어보기

FastAPI에서 함수 이름을 전부 notice로 똑같이 써도 서버가 돌아가. 왜 그런지 설명해줘. 그리고 이름을 다르게 쓰는 게 왜 좋은지도 알려줘.
(main.py 붙여넣기)
아래 코드에 /contact 주소를 추가하고 싶어. "연락처 입니다"가 나오게 코드를 어디에 어떻게 넣으면 되는지 알려줘.
(main.py 붙여넣기)

AI가 준 /contact 코드를 붙여 넣고 브라우저에서 확인해 보세요. 여러분이 손으로 친 세 개와 모양이 같을 것입니다. 이것이 이 책의 방식입니다. 뼈대를 알면 AI가 준 코드가 눈에 들어옵니다.