mif是一個專為後端微服務開發而設計的 C++11 Web 應用程式框架。此框架使用附加類型元資訊。
1.5.1
注意:主分支正在積極開發中,使用最新版本用於生產用途。
最後在 gcc 13.2 上測試
Linux(最後在 Ubuntu 23.10 上測試)
git clone https://github.com/tdv/mif.git
cd mif
./download_third_party.sh
mkdir build
cd build
cmake ..
make
make install
注意:在 Ubuntu 中,您可能需要安裝一些額外的軟體包:liblz4-dev、pkgconf、bison、flex
您可以嘗試使用 CMAKE_INSTALL_PREFIX 選擇安裝目錄
mif建置完成後,就可以建構範例了
cd mif /examples/{sample_project}
mkdir build
cd build
cmake ..
make
注意:要開發應用程序,您可以使用應用程式模板。下載mif專案後,請依照以下步驟操作
cd mif /template
mkdir build
cd build
cmake ..
make
之後,您可以更改此模板以建立自己的應用程式。此外,您可以使用範本中完成的範例。範例已完全完成,並且有一個用於建置本身的腳本。所有這些都位於 _docs 資料夾中。您可以在 wiki 中找到範例的詳細文件。
伺服器:
cd mif /exammples/{sample_project}/bin
./{sample_project}_server
客戶:
cd mif /exammples/{sample_project}/bin
./{sample_project}_client
請使用 --help 獲取有關運行範例的更多信息
原始碼
描述
此範例示範了簡單 HTTP 回顯伺服器的工作。 HTTP 回顯伺服器
// mif
# include < mif /application/http_server.h >
# include < mif /common/log.h >
# include < mif /net/http/constants.h >
class Application
: public mif ::Application::HttpServer
{
public:
using HttpServer::HttpServer;
private:
// mif .Application.HttpServer
virtual void Init ( mif ::Net::Http::ServerHandlers &handlers) override final
{
handlers[ " / " ] = [] ( mif ::Net::Http::IInputPack const &request,
mif ::Net::Http::IOutputPack &response)
{
auto data = request. GetData ();
mif _LOG (Info) << " Process request " " << request. GetPath () << request. GetQuery () << " "t Data: "
<< (data. empty () ? std::string{ " null " } : std::string{ std::begin (data), std::end (data)});
response. SetCode ( mif ::Net::Http::Code::Ok);
response. SetHeader ( mif ::Net::Http::Constants::Header::Connection::Value,
mif ::Net::Http::Constants::Value::Connection::Close::Value);
response. SetData ( std::move (data));
};
}
};
int main ( int argc, char const **argv)
{
return mif ::Application::Run<Application>(argc, argv);
}
測試
curl -iv -X POST " http://localhost:55555/ " -d ' Test data '
原始碼
描述
此範例示範了具有雙介面的 HTTP 伺服器的工作方式,用於處理原始 HTTP 請求和透過 HTTP 進行mif RPC。更多內容請參閱「Web 服務。附加」一章
原始碼
描述
「Hello World」範例示範了一個基本的客戶端-伺服器應用程序,具有基於介面的 RPC 編組和 TCP 通信,並使用 boost.archives 進行資料序列化
使用 RPC 建立客戶端-伺服器應用程式的基本步驟
通用介面
// STD
# include < string >
// mif
# include < mif /service/iservice.h >
namespace Service
{
struct IHelloWorld
: public mif ::Service::Inherit< mif ::Service::IService>
{
virtual void AddWord (std::string const &word) = 0;
virtual std::string GetText () const = 0;
virtual void Clean () = 0;
};
} // namespace Service
通用介面元資訊
// STD
# include < string >
// mif
# include < mif /remote/ps.h >
// THIS
# include " common/interface/ihello_world.h "
namespace Service
{
namespace Meta
{
using namespace ::Service ;
mif _REMOTE_PS_BEGIN (IHelloWorld)
mif _REMOTE_METHOD (AddWord)
mif _REMOTE_METHOD (GetText)
mif _REMOTE_METHOD (Clean)
mif _REMOTE_PS_END ()
} // namespace Meta
} // namespace Service
mif _REMOTE_REGISTER_PS (Service::Meta::IHelloWorld)
伺服器介面實現
...
// mif
# include < mif /service/creator.h >
// THIS
# include " common/id/service.h "
# include " common/interface/ihello_world.h "
namespace Service
{
namespace Detail
{
namespace
{
class HelloWorld
: public IHelloWorld
{
public:
...
private:
...
// IHelloWorld
virtual void AddWord (std::string const &word) override final
{
...
}
virtual std::string GetText () const override final
{
...
}
virtual void Clean () override final
{
...
}
};
} // namespace
} // namespace Detail
} // namespace Service
mif _SERVICE_CREATOR
(
::Service::Id::HelloWorld,
::Service::Detail::HelloWorld
)
伺服器應用
// mif
# include < mif /application/tcp_service.h >
// COMMON
# include " common/id/service.h "
# include " common/ps/ihello_world.h "
class Application
: public mif ::Application::TcpService
{
public:
using TcpService::TcpService;
private:
// mif .Application.TcpService
virtual void Init ( mif ::Service::FactoryPtr factory) override final
{
factory-> AddClass <Service::Id::HelloWorld>();
}
};
int main ( int argc, char const **argv)
{
return mif ::Application::Run<Application>(argc, argv);
}
客戶申請
// mif
# include < mif /application/tcp_service_client.h >
# include < mif /common/log.h >
// COMMON
# include " common/ps/ihello_world.h "
class Application
: public mif ::Application::TcpServiceClient
{
public:
using TcpServiceClient::TcpServiceClient;
private:
// mif .Application.TcpServiceClient
virtual void Init ( mif ::Service::IFactoryPtr factory) override final
{
auto service = factory-> Create <Service::IHelloWorld>( " HelloWorld " );
mif _LOG (Info) << " Add words. " ;
service-> AddWord ( " Hello " );
service-> AddWord ( " World " );
service-> AddWord ( " !!! " );
mif _LOG (Info) << " Result from server: " " << service-> GetText () << " " " ;
mif _LOG (Info) << " Clean. " ;
service-> Clean ();
mif _LOG (Info) << " Result from server: " " << service-> GetText () << " " " ;
}
};
int main ( int argc, char const **argv)
{
return mif ::Application::Run<Application>(argc, argv);
}
原始碼
描述
此範例與“Hello World”相同。差別在於以使用者定義的資料結構作為參數呼叫遠端方法並傳回一個值。專案結構與前面的專案範例相同,我們僅新增使用者定義的資料結構和元資訊的定義。
使用者資料結構
// STD
# include < cstdint >
# include < map >
# include < string >
namespace Service
{
namespace Data
{
using ID = std::string;
struct Human
{
std::string name;
std::string lastName;
std:: uint32_t age = 0 ;
};
enum class Position
{
Unknown,
Developer,
Manager
};
struct Employee
: public Human
{
Position position = Position::Unknown;
};
using Employees = std::map<ID, Employee>;
} // namespace Data
} // namespace Service
元資訊
// mif
# include < mif /reflection/reflect_type.h >
// THIS
# include " common/data/data.h "
namespace Service
{
namespace Data
{
namespace Meta
{
mif _REFLECT_BEGIN (Human)
mif _REFLECT_FIELD (name)
mif _REFLECT_FIELD (lastName)
mif _REFLECT_FIELD (age)
mif _REFLECT_END ()
mif _REFLECT_BEGIN (Position)
mif _REFLECT_FIELD (Unknown)
mif _REFLECT_FIELD (Developer)
mif _REFLECT_FIELD (Manager)
mif _REFLECT_END ()
mif _REFLECT_BEGIN (Employee, Human)
mif _REFLECT_FIELD (position)
mif _REFLECT_END ()
} // namespace Meta
} // namespace Data
} // namespace Service
mif _REGISTER_REFLECTED_TYPE (::Service::Data::Meta::Human)
mif _REGISTER_REFLECTED_TYPE(::Service::Data::Meta::Position)
mif _REGISTER_REFLECTED_TYPE(::Service::Data::Meta::Employee)
原始碼
描述
與前面的範例相比,這個範例新增了介面繼承。在實作中,您可以查詢超出層次結構的介面。
原始碼
描述
「Visitor」範例示範了介面方法的遠端回呼機制。這可以用作基於發布/訂閱的應用程式的起點。
原始碼
描述
此範例示範了 HTTP 伺服器上的 Json API(CRUD 操作)。
測試
curl -i -X POST " http://localhost:55555/employee/create " -d ' {"name":"Ivan", "lastName":"Ivanov","age":33,"email":"[email protected]","position":"Developer","rate":200000.00} '
curl -i " http://localhost:55555/employee/read?id=1 "
curl -i " http://localhost:55555/employee/update?id=1 " -d ' {"name":"Ivan", "lastName":"Ivanov","age":33,"email":"[email protected]","position":"Developer","rate":220000.00} '
curl -i " http://localhost:55555/employee/list?limit=2&offset=0 "
curl -i " http://localhost:55555/employee/delete?id=1 "
原始碼
描述
此範例演示了兩個微服務之間的通訊(該範例是 http crud 的更強大版本)。測試
./storage —config=storage.xml
./service --config=service.xml
curl -i -X POST " http://localhost:55555/employee/create " -d ' {"name":"Ivan", "lastName":"Ivanov","age":33,"email":"[email protected]","position":"Developer","rate":200000.00} '
curl -i " http://localhost:55555/employee/read?id=1 "
curl -i " http://localhost:55555/employee/update?id=1 " -d ' {"name":"Ivan", "lastName":"Ivanov","age":33,"email":"[email protected]","position":"Developer","rate":220000.00} '
curl -i " http://localhost:55555/employee/list?limit=2&offset=0 "
curl -i " http://localhost:55555/employee/delete?id=1 "
原始碼
描述
此範例演示了 C++ 資料結構反射的機制。這可以用作使用序列化、ORM 和 REST API 來建立應用程式的起點。