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.

To top To top

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.

To top To top

Running the example

./git https://api.github.com/orgs/Genivia/repos

This displays the Genivia public repos.

To top To top

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.](../../doc/xml-rpc-json/html/index.html) Implementing the client application ----------------------------------- The client application [`git.c`](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`](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](../../doc/xml-rpc-json/html/index.html) 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.](../../tutorials.html) Also see the [tutorials](../../tutorials.html) on how to set timeouts and handle signals. [![To top](../../images/go-up.png) To top](#) 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: [command] 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: [command] 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. [![To top](../../images/go-up.png) To top](#) Running the example ------------------- [command] ./git https://api.github.com/orgs/Genivia/repos This displays the Genivia public repos. [![To top](../../images/go-up.png) To top](#)