Menu

웹 서버(Web server)

vibe.d 를 이용해 HTTP(S) 프로토콜을 처리하는 웹 서버를 즉석으로 만들 수 있습니다.

    auto settings = new HTTPServerSettings;
    settings.port = 8080;
    listenHTTP(settings, &foo);

이 예제 코드는 8080포트에서 들어온 접속을 foo 라는 함수에게 전달해 HTTP 요청을 처리하도록 합니다.

listenHTTP에 전달될 함수는 HTTPServerRequestHTTPServerResponse 객체를 입력으로 받습니다. 여기에서는 foo 를 예로 들겠습니다.

    void foo(HTTPServerRequest req,
        HTTPServerResponse res) { ... }

물론 foo 와 같은 델리게이트에서 조건문을 사용해 HTTP 메소드와 경로별로 일일이 처리할 수도 있지만, 번거롭습니다.

이에 따라 HTTP 요청의 메소드(method)가 GET 인지 POST 인지 혹은 다른 것인지, 어떤 경로로 요청이 온건지에 따라 .get("path", handler).post("path", handler) 등 사전에 정의된 적절한 내부함수를 호출해주는 URLRouter 클래스가 편의를 위해 제공됩니다. 추가로 웹서버 상의 경로를 내부 함수로 연결해주는 웹 인터페이스 또한 등록이 가능합니다.

    auto router = new URLRouter;
    router.registerWebInterface(new WebService);
    listenHTTP(settings, router);

WebService 는 아래의 간단한 규칙에 따라 웹 서비스로 들어온 요청을 내부 함수로 연결해줍니다.

  • index() 함수명은 /index 경로를 요청할 때 호출됩니다.
  • getName() 함수명은 GET (get) 메소드로 /name (Name) 을 요청할 때 호출될 함수명의 형태입니다.
  • postUsername() 함수명은 POST (post) 메소드로 /username (Username) 을 요청할 때 호출될 함수명의 형태입니다.

이러한 규칙에 따르기 힘든 경로라면, 내부 함수를 선언할 때 @path("/hello/world") 형태로 속성을 정의해주면 됩니다. 특히, 내부함수 선언시 입력값의 이름 앞에 _ 를 붙이게 되면 POST 메소드로 요청을 처리할 수 있는 내부 함수가 됩니다. 그리고 내부 함수의 입력값으로 받아올 웹 요청 파라미터는 직접 @path 속성 내에 아래와 같이 지정할 수 있습니다.

:id 로 HTTP 요청에서 받아온 값은 int _id 내에 저장됩니다.

    @path("/my/api/:id")
    void foo(int _id)

HTTP 요청을 처리할 함수에 모두 HTTPServerRequestHTTPServerResponse 를 받도록 반드시 정의할 필요는 없습니다. 둘 중 하나만 적어도 되고, 아예 생략해도 됩니다.

vibe.d 프레임워크가 미리 검사하여, 파라미터로 전달할 필요가 없는 경우에는 그냥 넘어갑니다.

rdmd playground.d