-
Notifications
You must be signed in to change notification settings - Fork 146
RestControllers
REST Controllers provide custom execution logic for configured HTTP requests over specific HTTP methods. Request URI's and HTTP Verbs (GET,PUT,POST,DELETE etc) are mapped to configured C++ class methods.
All Serializable POCO objects can be mapped as request and response entities in a given rest controller.
We will consider a REST controller having the following functions
-
Add 2 numbers
-
Given base b and exponent n return the Exponentiation bn
-
Read a vector of integers and return the same as response
-
Read an Object and return the same
-
Read a vector of Objects and return the same
-
Upload a multipart form with one file and one parameter
-
Upload a multipart form with 3 files and one parameter
-
Upload a multipart form with a vector of files and one parameter
OneObject.h
#ifndef OneObject_H_ #define OneObject_H_ #include "string" using namespace std; class OneObject { int id; string name; public: OneObject(); virtual ~OneObject(); int getId() const; void setId(int); string getName() const; void setName(string); bool operator<(OneObject t) const; }; #endif
OtherObject.h
#ifndef OtherObject_H_ #define OtherObject_H_ #include "string" using namespace std; class OtherObject { public: int i; string j; float c; }; #endif
YetAnotherObject.h
#ifndef YetAnotherObject_H_ #define YetAnotherObject_H_ #include "OneObject.h" #include "vector" #include "OtherObject.h" #include "queue" #include "list" class YetAnotherObject { vector<int> vpi; public: OneObject t; int y; vector<int> vi; vector<string> vs; vector<double> vd; vector<long> vl; vector<bool> vb; vector<short> vsh; vector<OtherObject> vyo; list<int> li; std::queue<short> qsh; public: void setVpi(vector<int> vpi) { this->vpi = vpi; } vector<int> getVpi() { return vpi; } YetAnotherObject(); virtual ~YetAnotherObject(); }; #endif
ExampleRestController
(Header)
#ifndef ExampleRestController_H_ #define ExampleRestController_H_ #include <math.h> #include <iostream> #include "vector" #include "YetAnotherObject.h" #include <fstream> #include "CastUtil.h" #pragma @RestController path="/restful" class ExampleRestController { public: #pragma @GET path="/add" statusCode="200" int addNumbers( #pragma @QueryParam name="a" int, #pragma @QueryParam name="b" int); #pragma @GET path="/{b}/power/{n}" statusCode="200" double power( #pragma @PathParam name="b" int, #pragma @PathParam name="n" int); #pragma @POST path="/vectorI" statusCode="200" vector<int> testVector( #pragma @Body vector<int>); #pragma @POST path="/object" statusCode="200" YetAnotherObject testObject( #pragma @Body YetAnotherObject); #pragma @POST path="/vectorObject" statusCode="200" vector<YetAnotherObject> testVectorObject( #pragma @Body vector<YetAnotherObject> param); #pragma @POST path="/uploadOne" statusCode="200" string testUploadFile( #pragma @MultipartContent name="file" ifstream* ifs, #pragma @MultipartContent name="field" string param); #pragma @POST path="/uploadMulti" statusCode="200" string testUploadFileMulti1( #pragma @MultipartContent name="file1" ifstream* ifs1, #pragma @MultipartContent name="file2" ifstream* ifs2, #pragma @MultipartContent name="file3" ifstream* ifs3, #pragma @MultipartContent name="field" string param); #pragma @POST path="/uploadVecFiles" statusCode="200" string testUploadFileMulti2( #pragma @MultipartContent name="files" vector<ifstream*> vifs, #pragma @MultipartContent name="field" string param); }; #endif
(Source)
#include "ExampleRestController.h" int ExampleRestController::addNumbers(int a, int b) { cout << "Processed input request inside ExampleRestController for addNumbers..." << endl; return a + b; } double ExampleRestController::power(int base, int exponent) { cout << "Processed input request inside ExampleRestController for power..." << endl; return pow((double)base, (double)exponent); } vector<int> ExampleRestController::testVector(vector<int> param) { cout << "Processed input request inside ExampleRestController for testVector..." << endl; return param; } YetAnotherObject ExampleRestController::testObject(YetAnotherObject YetAnotherObject) { cout << "Processed input request inside ExampleRestController for testObject..." << endl; return YetAnotherObject; } vector<YetAnotherObject> ExampleRestController::testVectorObject(vector<YetAnotherObject> param) { cout << "Processed input request inside ExampleRestController for testVectorObject..." << endl; return param; } string ExampleRestController::testUploadFile(ifstream* ifs, string param) { string vals; unsigned int siz = 0; if (ifs!=NULL && ifs->is_open()) { ifs->seekg(0, ios::end); siz = ifs->tellg(); } vals = "Uploaded File Size = " + CastUtil::lexical_cast<string>(siz); vals += "\nField value passed = " + param; cout << "Processed input request inside ExampleRestController for testUploadFile..." << endl; return vals; } string ExampleRestController::testUploadFileMulti1(ifstream* ifs1, ifstream* ifs2, ifstream* ifs3, string param) { string vals; unsigned int siz = 0; if (ifs1!=NULL && ifs1->is_open()) { ifs1->seekg(0, ios::end); siz = ifs1->tellg(); } vals = "Uploaded File1 Size = " + CastUtil::lexical_cast<string>(siz); siz = 0; if (ifs2!=NULL && ifs2->is_open()) { ifs2->seekg(0, ios::end); siz = ifs2->tellg(); } vals += "\nUploaded File2 Size = " + CastUtil::lexical_cast<string>(siz); siz = 0; if (ifs3!=NULL && ifs3->is_open()) { ifs3->seekg(0, ios::end); siz = ifs3->tellg(); } vals += "\nUploaded File3 Size = " + CastUtil::lexical_cast<string>(siz); vals += "\nField value passed = " + param; cout << "Processed input request inside ExampleRestController for testUploadFileMulti1..." << endl; return vals; } string ExampleRestController::testUploadFileMulti2(vector<ifstream*> vifs, string param) { string vals; for(int i=0;i<(int)vifs.size();++i) { ifstream* ifs = vifs.at(i); unsigned int siz = 0; if (ifs!=NULL && ifs->is_open()) { ifs->seekg(0, ios::end); siz = ifs->tellg(); } vals += "Uploaded File" + CastUtil::lexical_cast<string>(i) + " Size = " + CastUtil::lexical_cast<string>(siz) + "\n"; } vals += "Field value passed = " + param; cout << "Processed input request inside ExampleRestController for testUploadFileMulti2..." << endl; return vals; }
(Headers)
ExampleRestController.h
#ifndef ExampleRestController_H_ #define ExampleRestController_H_ #include <math.h> #include <iostream> #include "vector" #include "YetAnotherObject.h" #include <fstream> #include "CastUtil.h" class ExampleRestController { public: int addNumbers(int,int); double power(int,int); vector<int> testVector(vector<int>); YetAnotherObject testObject(YetAnotherObject); vector<YetAnotherObject> testVectorObject(vector<YetAnotherObject> param); string testUploadFile(ifstream* ifs, string param); string testUploadFileMulti1(ifstream* ifs1, ifstream* ifs2, ifstream* ifs3, string param); string testUploadFileMulti2(vector<ifstream*> vifs, string param); }; #endif
(Source)
Same as above
(Configuration)
<app> <restcontrollers> <restcontroller class="ExampleRestController" path="/rest/path/rest1/"> <restfunction name="addNumbers" path="add/{1}/{2}" meth="GET" statusCode="200"> <param type="int" name="1" from="path" /> <param type="int" name="2" from="path" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/rest/reqparam/rest1/"> <restfunction name="addNumbers" path="add" meth="GET" statusCode="200"> <param type="int" name="1" from="reqparam" /> <param type="int" name="2" from="reqparam" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/rest/postparam/rest1/"> <restfunction name="addNumbers" path="add" meth="POST" statusCode="200"> <param type="int" name="1" from="postparam" /> <param type="int" name="2" from="postparam" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/rest/header/rest1/"> <restfunction name="addNumbers" path="add" meth="GET" statusCode="200"> <param type="int" name="a" from="header" /> <param type="int" name="b" from="header" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/rest/path1/rest2"> <restfunction name="addNumbers" path="+/{1}/{2}" meth="GET" statusCode="200"> <param type="int" name="1" from="path" /> <param type="int" name="2" from="path" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/rest3"> <restfunction name="addNumbers" path="ad/{1}/{2}" meth="GET" statusCode="200"> <param type="int" name="1" from="path" /> <param type="int" name="2" from="path" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController"> <restfunction name="power" meth="GET" path="/rest/controller/base{1}/power/exp{2}" statusCode="200"> <param type="int" name="1" from="path" /> <param type="int" name="2" from="path" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController"> <restfunction name="addNumbers" meth="GET" path="/addNumbers/{1}/{2}" statusCode="200"> <param type="int" name="1" from="path" /> <param type="int" name="2" from="path" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restvec"> <restfunction name="testVector" path="tstvec" meth="POST" statusCode="200"> <param type="vector-of-int" from="body" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restvecobj"> <restfunction name="testVectorObject" path="tstvecobj" meth="POST" icontentType="application/json" statusCode="200"> <param type="vector-of-YetAnotherObject" from="body" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restobj"> <restfunction name="testObject" path="tstobj" meth="POST" icontentType="application/json" ocontentType="application/json" statusCode="200"> <param type="YetAnotherObject" from="body" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restvecobj"> <restfunction name="testVectorObject" path="tstvecobj.xml" meth="POST" icontentType="application/xml" statusCode="200"> <param type="vector-of-YetAnotherObject" from="body" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restobj"> <restfunction name="testObject" path="tstobj.xml" meth="POST" icontentType="application/xml" statusCode="200"> <param type="YetAnotherObject" from="body" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restupload"> <restfunction name="testUploadFile" path="uploadFile" meth="POST" icontentType="multipart/form-data" statusCode="200"> <param type="filestream" name="file" from="multipart-content" /> <param type="string" name="field" from="multipart-content" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restupload"> <restfunction name="testUploadFileMulti1" path="uploadFileMulti1" meth="POST" icontentType="multipart/form-data" statusCode="200"> <param type="filestream" name="file1" from="multipart-content" /> <param type="filestream" name="file2" from="multipart-content" /> <param type="filestream" name="file3" from="multipart-content" /> <param type="string" name="field" from="multipart-content" /> </restfunction> </restcontroller> <restcontroller class="ExampleRestController" path="/restupload"> <restfunction name="testUploadFileMulti2" path="uploadFileMulti2" meth="POST" icontentType="multipart/form-data" statusCode="200"> <param type="vector-of-filestream" name="files" from="multipart-content" /> <param type="string" name="field" from="multipart-content" /> </restfunction> </restcontroller> </restcontrollers> </app>