mif เป็นเฟรมเวิร์กเว็บแอปพลิเคชัน C++11 ที่ออกแบบมาสำหรับการพัฒนาไมโครเซอร์วิสแบ็กเอนด์ กรอบงานใช้ข้อมูลเมตาประเภทเพิ่มเติม
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 คุณสามารถดูเอกสารประกอบโดยละเอียดของตัวอย่างได้ในวิกิ
เซิร์ฟเวอร์:
cd mif /exammples/{sample_project}/bin
./{sample_project}_server
ลูกค้า:
cd mif /exammples/{sample_project}/bin
./{sample_project}_client
โปรดใช้ --help เพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับการเรียกใช้ตัวอย่าง
ซอร์สโค้ด
คำอธิบาย
ตัวอย่างนี้สาธิตการทำงานของเซิร์ฟเวอร์ HTTP echo แบบธรรมดา HTTP-echo-เซิร์ฟเวอร์
// 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 แบบดิบและ mif RPC ด้วย HTTP สามารถดูเพิ่มเติมได้ในบท “บริการเว็บ เพิ่มเติม”
ซอร์สโค้ด
คำอธิบาย
ตัวอย่าง "Hello World" สาธิตแอปพลิเคชันไคลเอนต์-เซิร์ฟเวอร์พื้นฐานพร้อม RPC marshaling บนอินเทอร์เฟซและการสื่อสาร 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)
ซอร์สโค้ด
คำอธิบาย
เมื่อเปรียบเทียบกับตัวอย่างก่อนหน้านี้ ตัวอย่างนี้จะเพิ่มการสืบทอดอินเทอร์เฟซ ในการใช้งาน คุณสามารถสืบค้นอินเทอร์เฟซที่ไม่อยู่ในลำดับชั้นได้
ซอร์สโค้ด
คำอธิบาย
ตัวอย่าง "ผู้เยี่ยมชม" แสดงให้เห็นถึงกลไกของการโทรกลับระยะไกลสำหรับวิธีการอินเทอร์เฟซ ซึ่งสามารถใช้เป็นจุดเริ่มต้นสำหรับการเผยแพร่/สมัครสมาชิกแอปพลิเคชัน
ซอร์สโค้ด
คำอธิบาย
ตัวอย่างนี้สาธิต Json API (การดำเนินการ CRUD) บนเซิร์ฟเวอร์ HTTP
ทดสอบ
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