GitHub JSON API example
Overview
This example implements a GitHub JSON API client in C.
For more information about the use of JSON in gSOAP, see the JSON documentation.
Implementing the client application
The client application git.c
is run at the command line and takes the URL of a repo and optional username and password as the command-line arguments to display the GitHub repo in JSON:
#include "json.h"
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "Usage: git URL [username password]\nFor example: git https://api.github.com/orgs/Genivia/repos\n\n");
exit(0);
}
else
{
struct soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT);
struct value response;
ctx->send_timeout = 10; /* 10 sec, stop if server is not accepting msg */
ctx->recv_timeout = 10; /* 10 sec, stop if server does not respond in time */
if (argc > 3)
{
/* Basic authentication with username password */
if (strncmp(argv[1], "https", 5))
{
fprintf(stderr, "Basic authentication over http is not secure: use https\n");
exit(1);
}
ctx->userid = argv[2];
ctx->passwd = argv[3];
}
if (json_call(ctx, argv[1], NULL, &response))
soap_print_fault(ctx, stderr);
else
json_write(ctx, &response);
printf("\n\nOK\n");
soap_end(ctx);
soap_free(ctx);
}
return 0;
}
/* Don't need a namespace table. We put an empty one here to avoid link errors */
struct Namespace namespaces[] = { {NULL, NULL} };
The C++ implementation git.cpp
is very similar. However, in general, working with JSON data in C++ is a lot easier.
The context ctx
is initialized with SOAP_C_UTFSTRING
to ensure 8-bit strings contain Unicode in UTF-8 format. The SOAP_XML_INDENT
flag is optional, it displays JSON with an indented layout (just as XML is indented with this flag).
The struct value
data represents a JSON value (and in fact also an XML-RPC value).
The GitHub API is called with json_call(ctx, "URL", NULL, &response)
using an HTTP GET because the input parameter is NULL. The response JSON value is displayed with json_write(ctx, &response)
.
The call json_call(ctx, "URL", in, out))
with pointers in
and out
to JSON values supports HTTP POST (both in
and out
are non-NULL), HTTP GET (in
is NULL, out
is non-NULL), HTTP PUT (in
is non-NULL, out
is NULL), and HTTP DELETE (in
and out
are NULL).
JSON values can be read with json_read(ctx, v)
with pointer v
to an (empty) JSON value that will be assigned. To read from a file descriptor, set the context ctx->recvfd
to the descriptor. To read from a string, set the context ctx->is
to a char*
string which works in C only. In C++ set the context ctx->is
input stream to a string stream.
JSON values can be written with json_write(ctx, v)
with pointer v
to a JSON value that will be saved. To write to a file descriptor, set the context ctx->sendfd
to the descriptor. To write to a string, set the context ctx->os
to point to a char*
to be assigned with the string saved, which works in C only. In C++ set the context ctx->os
output stream to a string stream.
See the JSON documentation for more details on the JSON functions to create, inspect, and retrieve values.
Authentication credentials are set with the context ctx->userid
and ctx->password
strings. For more information about authentication and HTTPS, see the tutorials.
Also see the tutorials on how to set timeouts and handle signals.
Build steps for the client application
The use of JSON requires a one-time step to generate a data model that supports both JSON and the older XML-RPC protocols:
soapcpp2 -c -CSL xml-rpc.h
The xml-rpc.h
file and all other source code files that we need can be found in the samples/xml-rpc-json
directory of the gSOAP package.
To build the example client application we need stdsoap2.h
, stdsoap2.c
, json.h
, json.c
, xml-rpc.c
and the generated soapStub.h
, soapH.h
, and soapC.c
files:
cc -DWITH_OPENSSL -DWITH_GZIP -o git git.c xml-rpc.c json.c \
stdsoap2.c soapC.c -lcrypto -lssl -lz
This may look odd, to include "soap-related" files in the build steps, but this is with a reason. We can combine JSON with all of our XML/SOAP Web services by simply adding an #import "xml-rpc.h"
to the header file for soapcpp2 to process. The xml-rpc.h
file specifies the data model to support JSON and XML-RPC. When combining XML/SOAP with JSON, we compile the json.c
and xml-rpc.c
files also, as shown.
OpenSSL and Zlib are required for our client application to work propertly with HTTPS.
Running the example
./git https://api.github.com/orgs/Genivia/repos
This displays the Genivia public repos.