Ways to implement a JSON RESTful service in C/C++ - c++

I am trying to do a JSON Restful web service in C/C++.
I have tried Axis2/C and Staff, which work great for XML serialization/deserialization but not for JSON.

You might want to take a look at Casablanca introduced in Herb Sutter's blog.

there are a small number of libraries that support creating rest services with c, e.g. restinio:
#include <restinio/all.hpp>
int main()
{
restinio::run(
restinio::on_this_thread()
.port(8080)
.address("localhost")
.request_handler([](auto req) {
return req->create_response().set_body("Hello, World!").done();
}));
return 0;
}

try https://github.com/babelouest/ulfius great library to build C/C++ Restful APIs. can support all platforms: Linux, FreeBSD, Windows and others

Try ngrest. It's a simple but fast C++ RESTful JSON Web Services framework. It can be deployed on top of Apache2, Nginx or own simple http server.
Regarding Axis2/C with JSON. It's seems that official Axis2/C no longer maintained. So Axis2/C become obsolete (but still works).
JSON support for Axis2/C is available in axis2c-unofficial project.
There are an installation manuals on how to install Axis2/C with JSON support under Linux, Windows using binary package, Windows from source code.
You can try it with WSF Staff using Customers (REST) example in JSON mode (which is available from staff/samples/rest/webclient directory of staff source code).

You could look at ffead-cpp. Apart from providing support for json and restfull web services it also includes more features. This framework may be too heavy weight for your situation though.

For C++ web service, I am using the following stack:
ipkn/crow C++ micro web framework
nlohmann/json for json serialization/deserialization.

Take a look at Oat++
It has:
URL routing with URL-parameters mapping
Support for Swagger-UI endpoint annotations.
Object-Mapping with JSON support.
Example endpoint:
ENDPOINT("GET", "users/{name}", getUserByName, PATH(String, name)) {
auto userDto = UserDto::createShared();
userDto->name = name;
return createDtoResponse(Status::CODE_200, userDto);
}
Curl:
$ curl http://localhost:8000/users/john
{"name":"john"}

You may want to take a look at webcc.
It's a lightweight C++ HTTP client and server library for embedding purpose based on Boost.Asio (1.66+).
It's quite promising and actively being developed.
It includes a lot of examples to demonstrate how to create a server and client.

There is a JIRA project resolved the support of JSON in AXIS2/C .
I implemented in my project and I managed with the writer (Badgerfish convention) but still I am trying to manage with the reader.It seems more complicated managing with the stack in the memory.

JSON and JSONPath are supported for both C and C++ in gsoap with a new code generator and a new JSON API to get you started quickly.
Several JSON, JSON-RPC and REST examples are included. Memory management is automatic.
The code generator can be useful. Take for example the json.org menu.json snippet:
{ "menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
}
The gsoap command jsoncpp -M menu.json generates this code to populate a JSON value:
value x(ctx);
x["menu"]["id"] = "file";
x["menu"]["value"] = "File";
x["menu"]["popup"]["menuitem"][0]["value"] = "New";
x["menu"]["popup"]["menuitem"][0]["onclick"] = "CreateNewDoc()";
x["menu"]["popup"]["menuitem"][1]["value"] = "Open";
x["menu"]["popup"]["menuitem"][1]["onclick"] = "OpenDoc()";
x["menu"]["popup"]["menuitem"][2]["value"] = "Close";
x["menu"]["popup"]["menuitem"][2]["onclick"] = "CloseDoc()";
Also reading parsed JSON values and JSONPath code can be generated by this tool.
EDIT
To clarify, the jsoncpp command-line code generator shows the API code to read and write JSON data by using a .json file as a template, which I found is useful to save time to write the API code to populate and extract JSON data. JSONPath query code can also be generated with this tool.

For web service in C, you can leverage library like ulfius, civetweb:
https://github.com/babelouest/ulfius
https://github.com/civetweb/civetweb/blob/master/docs/Embedding.md
For web service in C++, you can leverage library like libhv, restbed:
https://github.com/ithewei/libhv
https://github.com/Corvusoft/restbed

Related

The App Insights API is deprecated and will stop working - What are the alternatives?

As of version 3.0 the App Insights API is deprecated.
Unfortunately I rely heavily on the app_event node to fetch information about the revenue. The code for that looks like this:
requests.request(
"GET",
"https://graph.facebook.com/v2.12/" + str(app_id) + "/app_insights/app_event/",
params={
"since":d1.strftime("%s"),
"until":d2.strftime("%s"),
"summary":"true",
"event_name":"fb_ad_network_revenue",
"aggregateBy": "SUM",
"breakdowns[0]":"placement",
"access_token": app_access_token
}
)
For new Apps I can't use this code anymore because the Graph API does not support it anymore:
The app tried to call version v2.12. This app can only call versions
v3.0 and higher, so the request defaulted to version v3.0.
How could I possibly port my code to version 3.0?
I ran into this problem as well. It looks like you can use the adnetworkanalytics endpoint now for this query. The parameters and data returned are of course slightly different than the app_event endpoint. Hurray for progress I guess.
Here are the docs:
https://developers.facebook.com/docs/audience-network/reporting-api

Restlet + JAXRS extension - how to use filters?

I have a REST service implemented in Restlet + JAXRS extension.
At a certain point, I had to add the CORS headers to responses.
I have a lot of REST calls, and adding by hand the headers as this is working:
return Response.status(200).header("Access-Control-Allow-Origin", "*").
header("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type").
header("Access-Control-Expose-Headers", "Location, Content-Disposition").
header("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, HEAD, OPTIONS").
entity(fsJSON).build();
but I'd like to use filters in order to add those headers to all the responses, without adding those manually. I found a lot of examples of using filters in JAX-RS, like those:
https://jersey.java.net/documentation/latest/filters-and-interceptors.html
http://javatech-blog.blogspot.it/2015/04/jax-rs-filters-example.html
http://blog.dejavu.sk/2014/02/04/filtering-jax-rs-entities-with-standard-security-annotations/
But I can't understand how to integrate them with Restlet + JAX-RS environment. For example, I can't see the ContainerResponseFilter class anywhere.
Anyone can help me?
When creating a JaxRS application within Restlet, you create a JaxRsApplication (see this link: http://restlet.com/technical-resources/restlet-framework/guide/2.2/extensions/jaxrs). This class extends the standard application of Restlet. The latter provides the way to configure services on it using the getServices method.
So in your case, you don't need to use filters...
See this answer regarding the configuration of the CorsService of Restlet: How to use CORS in Restlet 2.3.1?.
Here a way to configure CORS within a Restlet JaxRS application:
Component comp = new Component();
Server server = comp.getServers().add(Protocol.HTTP, 8182);
JaxRsApplication application = new JaxRsApplication(comp.getContext());
application.add(new ExampleApplication());
CorsService corsService = new CorsService();
corsService.setAllowedOrigins(new HashSet(Arrays.asList("*")));
corsService.setAllowedCredentials(true);
application.getServices().add(corsService);
component.getDefaultHost().attachDefault(application);
Otherwise JAX-RS filters aren't supported by the corresponding extensions of Restlet. To add a filter, you need to add it as a Restlet filter in front of the application, as described below:
JaxRsApplication application = new JaxRsApplication(comp.getContext());
application.add(new ExampleApplication());
MyRestletFilter filter = new MyRestletFilter();
filter.setNext(application);
component.getDefaultHost().attachDefault(filter);
Hope it helps you,
Thierry

Dynamics Nav exchange with Groupon

I need to build an interface between Dynamics NAV 2013 and Groupon API V2
It seems to me that Groupons API data comes in json format - how could I get this information in Dynamics NAV (orders for example) ?
Should I use webservices ?
Thanks
EDIT :
I worked a lot on this and got receiving data from groupon working
The problem is send information :
I have a problem to send a post request with parameters - this is my code :
WebServiceURL := 'https://...';
Request := Request.Create(WebServiceURL);
Request.Method := 'POST';
Request.KeepAlive := TRUE;
Request.Timeout := 30000;
Request.Accept('application/json');
Request.ContentType('multipart/form-data');
postString := 'param1=123&param2=456';
Request.ContentLength := STRLEN(postString);
StreamWriter := StreamWriter.StreamWriter(Request.GetRequestStream);
StreamWriter.Write(postString);
StreamWriter.Close;
I get a 500 error so I don't know anything about why its rejected
But if there is something that seems to be wrong to you, please help !
the most NAV frienly way is to get the order in XML format from the API and import the XMLs using XMLports or Codeunits(use DotNet)
Cheers
You don't need Nav web services because in this case you are (Nav) the client side, when web services is to build the server side. E.g. you can call web service but web service can not call anything. Most probably you will use NAS to perform tasks periodically.
AFAIK Nav can't handle JSON, but in Nav2013 it's possible to use .Net libraries so just pick JSON library you like and call it from Nav to process responses from API.
To make calls(requests) to API you can use .net or com library of your choise just the same was as for JSON.
ReqXML : Automation 'Microsoft XML, v6.0'.DOMDocument60
RespXML: Automation 'Microsoft XML, v6.0'.DOMDocument60
Req : Automation 'Microsoft XML, v6.0'.XMLHTTP60
CREATE(Req, TRUE);
Req.open(reqType, Uri, FALSE);
Req.setRequestHeader('contentType', 'text/xml; charset=UTF-16');
CASE reqType OF
'GET': Req.send();
'POST': Req.send(ReqXML);
END;
RespText := Req.statusText;
IF Req.status <> 200 THEN EXIT(FALSE);
IF ISCLEAR(RespXML) THEN CREATE(RespXML, TRUE);
RespXML.load(Req.responseXML);
In this example request to address stored in Uri is made. If you need to post some data aside from URL parameters then you put it to ReqXML. If API is suppose to return something it will be inside RespXML.
This code works for older versions of Nav. You will have to rewrite it a little to use .Net libraries (like webclient) and maybe get rid of XML (in my case API was XML based) but the structure will be pretty much the same.

Creating simple WebService in C++ / Qt (acting as server) providing JSON data

I need to create a simple web service (being the "server"). The goal is to provide some data I do read in an Qt / C++ application as JSON data. Basically a JavaScript application in the browser shall read its data from the Qt app. It is usually a single user scenario, so the user runs a Google Maps application in her browser, while additional data come from the Qt application.
So far I have found these libs:
Qxt: http://libqxt.bitbucket.org/doc/0.6/index.html but being a newbie on C++/Qt I miss some examples. Added: I have found one example here
gSoap: http://www.cs.fsu.edu/~engelen/soap.html has more examples and documentation and also seems to support JSON
KD SOAP: http://www.kdab.com/kdab-products/kd-soap/ with no example as far as I can tell, docu is here
Qt features itself, but it is more about acting as a client: http://qt-project.org/videos/watch/qt-networking-web-services
Checking SO gives me basically links to the above libs
webservice with Qt with an example I do not really get.
How to Create a webservice by Qt
So basically I do have the following questions:
Which lib would you use? I want to keep it as simple as possible and would need an example.
Is there another (easy!) way to provide the JSON data to the JavaScript Web page besides the WebService?
-- Edit, remarks: ---
Needs to be application intrinsic. No web server can be installed, no extra run time can be used. The user just runs the app. Maybe the Qt WebKit could be an approach....
-- Edit 2 --
Currently checking the tiny web servers as of SO " Qt HTTP Server? "
As of my tests, currently I am using QtWebApp: http://stefanfrings.de/qtwebapp/index-en.html This is one of the answers of Edit 2 ( Qt HTTP Server? )
Stefan's small WebServer has some well documented code, is written in "Qt C++" and easy to use, especially if you have worked with servlets already. Since it can be easily integrated in my Qt project, I'll end up with an internal WebServer.
Some demo code from my JSON tests, showing that generating the JSON content is basically creating a QString.
void WebServiceController::service(HttpRequest& request, HttpResponse& response) {
// set some headers
response.setHeader("Content-Type", "application/json; charset=ISO-8859-1");
response.setCookie(HttpCookie("wsTest","CreateDummyPerson",600));
QString dp = WebServiceController::getDummyPerson();
QByteArray ba = dp.toLocal8Bit();
const char *baChar = ba.data();
response.write(ba);
}
If someone has easy examples with other libs to share, please let me know.
QByteArray ba = dp.toLocal8Bit();
const char *baChar = ba.data();
You don't need to convert the QByteArray to char array. Response.write() can also be called with a QByteArray.
By the way: qPrintable(dp) is a shortcut to convert from QString to char array.

Using libcurl to upload files to DropBox

I'm trying to use the libcurl in a C/C++ application to post files to DropBox.
I would like to use the "/files (POST)" API as documented here...
https://www.dropbox.com/developers/reference/api#files-POST
I am having problems with properly authenticating (OAuth) this call. It is unclear to me how to properly create the authentication signature.
From some a sample I saw, it looked like they were reading in the whole file to create the HMAC-SHA1 encoding on. This seems problematic on large files.
Does anyone have experience or insight using this API or something similar?
I have just use the libouth and libcurl to get information from sina weibo. here is my example for you refer. you can also refer the liboauth test programmer in the tests dir, oauthtest.c
if (use_post)
{
req_url = oauth_sign_url2(test_call_uri, &postarg, OA_HMAC, NULL, c_key, c_secret, t_key, t_secret);
reply = oauth_http_post(req_url,postarg);
}
I suggest using BOOST ASIO . Makes uploading and downloading a breeze.