개요
C++ Native Deamon 소프트웨어들은 전통적으로 TCP/IP소켓을 통해 서로 통신하는게 일반적이었습니다. 하지만 최근 Restful API가 대세로 자리 잡으면서 일반적인 데이터 통신시 HTTP방식으로의 연동을 많이 사용합니다.
최근 프로젝트에서 기존에 C++로 개발된 서버에 연동규격을 Restful API로 변경하는 작업을 진행하였는데 그 떄 사용했던 프레임워크에 대해서 간략히 소개합니다.
RestBed
Restbed는 RESTful API Server 애플리케이션을 구축하기 위한 C++11 라이브러리입니다. HTTP 요청 및 응답 처리, JSON 구문 분석 및 직렬화, 비동기 처리 등을 포함하여 RESTful API를 구축하기 위한 포괄적인 기능이 제공합니다. Restbed는 유연하고 효율적이며 사용하기 쉽도록 설계되어 C++로 RESTful API를 구축하는 데 사용될 수 있습니다. Restbed를 사용하면 HTTP 요청을 처리하고 동적 콘텐츠를 제공하기 위한 코드를 작성할 수 있으며 인증, 속도 제한 및 로깅과 같은 기능을 사용하여 API에 기능을 추가할 수도 있습니다.
장점
1.심플함
Restbed는 RESTful API를 구축하기 위한 유연한 프레임워크를 제공하여 들어오는 요청에 대한 사용자 지정 엔드포인트 및 핸들러를 간단하고 직관적으로 정의할 수 있습니다.
2.효율적인 처리
Restbed는 들어오는 HTTP 요청을 효율적으로 처리하도록 설계되어 비동기 처리, 연결 풀링 등을 위한 기능을 제공합니다.
3.JSON 지원
Restbed에는 JSON 데이터 구문 분석 및 직렬화 지원이 포함되어 있어 API에서 JSON을 쉽게 사용할 수 있습니다.
4.다큐먼트
문서화가 비교적 잘되어 있고 예제도 다양하게 지원합니다.
5.Cross Flatform
Restbed는 Windows, macOS 및 Linux를 포함한 여러 운영 체제를 지원합니다. 개인적으로 가장 큰 장점이라 생각합니다.
단점
1.제한된 커뮤니티
Restbed는 다른 RESTful API 프레임워크만큼 널리 사용되지 않아 입맛에 맞는 도움말과 리소스를 찾기가 더 어려울 수 있습니다.
2.복잡한 API
Restbed는 많은 기능과 옵션을 제공하므로 이를 사용하고 API를 구성하는 방법을 이해하기 어려울 수 있습니다.
3.성능 오버헤드
Restbed는 트래픽이 많은 API의 성능에 영향을 줄 수 있는 API에 약간의 오버헤드를 추가할 수 있습니다.
4.디버깅
복잡한 API에서 문제의 원인을 추적하는 것이 어려울 수 있으므로 Restbed 문제를 디버깅하는 것은 어려울 수 있습니다.
전반적으로 Restbed는 C++에서 RESTful API를 구축하기 위한 좋은 선택이지만 사용 가능한 유일한 옵션은 아니며 프레임워크 선택은 특정 요구 사항과 요구 사항에 따라 달라집니다. JSON 및 크로스 플랫폼 개발을 잘 지원하는 유연하고 효율적인 API 프레임워크를 찾고 있다면 Restbed가 좋은 선택일 수 있습니다.
Install
Windows, Linux 또는 macOS 컴퓨터에 Restbed API를 설치하려면 다음 단계가 필요합니다.
소스코드 다운로드: Restbed용 소스코드는 github에서 (https://github.com/Corvusoft/restbed) 다운로드할 수 있습니다.
라이브러리 빌드: 소스 코드를 다운로드한 후 다음 명령을 실행하여 라이브러리를 빌드해야 합니다.
git clone https://github.com/corvusoft/restbed.git
mkdir restbed/build
cd restbed/build
cmake [-DBUILD_SSL=NO] [-DBUILD_TESTS=NO] ..
make install
make test
Windows환경에서는 직접 빌드보다 vpckg로 설치하는 편을 추천합니다.(보다 간단합니다.)
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install restbed
사용하기
#include <memory>
#include <cstdlib>
#include <restbed>
using namespace std;
using namespace restbed;
// resource handler함수
void post_method_handler( const shared_ptr< Session > session )
{
const auto request = session->get_request( );
int content_length = request->get_header( "Content-Length", 0 );
session->fetch( content_length, [ ]( const shared_ptr< Session > session, const Bytes & body )
{
fprintf( stdout, "%.*s\n", ( int ) body.size( ), body.data( ) );
session->close( OK, "Hello, World!", { { "Content-Length", "13" } } );
} );
}
// resource2 handler함수, 파라메터는 동일합니다.
void post_method_handler2( const shared_ptr< Session > session )
{
const auto request = session->get_request( );
int content_length = request->get_header( "Content-Length", 0 );
session->fetch( content_length, [ ]( const shared_ptr< Session > session, const Bytes & body )
{
fprintf( stdout, "%.*s\n", ( int ) body.size( ), body.data( ) );
session->close( OK, "Hello, World!", { { "Content-Length", "13" } } );
} );
}
int main( const int, const char** )
{
// URL별로 resource객체를 생성합니다.
auto resource = make_shared< Resource >( );
resource->set_path( "/post/v1/resource" );
resource->set_method_handler( "POST", post_method_handler );
auto resource2 = make_shared< Resource >( );
resource2->set_path( "/post/v1/about" );
resource2->set_method_handler( "POST", post_method_handler2 );
auto settings = make_shared< Settings >( );
settings->set_port( 1984 );
settings->set_default_header( "Connection", "close" );
Service service;
// 생성된 모든 resource는 반드시 publish해야 동작합니다.
service.publish( resource );
service.publish( resource2 );
service.start( settings );
return EXIT_SUCCESS;
}
각 path별로 Handler함수를 등록해야 합니다. 예제와는 다르게 실제 서비스 구현시 Handler함수는 별도의 소스파일에 작성하는게 향후 유지보수에 좋을 것 같습니다.
두번째 예제입니다.
#include <restbed>
using namespace restbed;
void wildcard_handler(const shared_ptr<Session> session)
{
const auto request = session->get_request();
const auto path = request->get_path();
const auto method = request->get_method();
string response = "Hello from the wildcard handler!\n";
response += "Method: " + method + "\n";
response += "Path: " + path + "\n";
session->close(OK, response, { { "Content-Length", to_string(response.length()) } });
}
int main(const int, const char**)
{
auto resource = make_shared<Resource>();
resource->set_path("/.*");
resource->set_method_handler("GET", wildcard_handler);
auto settings = make_shared<Settings>();
settings->set_port(8080);
Service service;
service.publish(resource);
service.start(settings);
return 0;
}
WildCard(/.*)를 등록하면 지정되지 않는 모든 URL 요청을 처리합니다.
다음은 로깅기능을 추가합니다. Tomcat에서 제공되는 access log와 비슷하게 모든 접속기록을 기록합니다. 로깅을 활성화 해두면 나중에 유지보수중에 문제가 발생할 경우 해결의 실마리를 제공할 수 있습니다.
https://github.com/Corvusoft/restbed/blob/master/documentation/example/LOGGING.md
GitHub - Corvusoft/restbed: Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications.
Corvusoft's Restbed framework brings asynchronous RESTful functionality to C++14 applications. - GitHub - Corvusoft/restbed: Corvusoft's Restbed framework brings asynchronous RESTful functi...
github.com
마지막으로 RedtBed에 대한 주관적인 견해입니다. Redtbed은 복잡한 Restful API 서버 구현으로는 적합하진 않으나 C++로 Windows, Linux에서 Portable하게 사용할 수 있는 간단한 API구현으로 좋은 선택이 될 수 있습니다.
읽어주셔서 감사합니다.