![]() |
libcurlA common method for accessing Hypertext Transfer Protocol (HTTP) 1) 2) based services using C/C++ is using libcurl 3). Since REST Web Services are based on HTTP, libcurl can be used to access any REST service. InstallationThe libcurl library is installed via:
HTTP GETHTTP GET is simplest of the HTTP requests and is used to get a document given a URL. So to use a GET the URL of the required Web Service resource is needed. Depending on the service this may be a static URL or more commonly the URL has to be constructed based on the parameters for the request. The following examples illustrate the process using the dbfetch and WSDbfetch (REST) services. dbfetchThe dbfetch service (http://www.ebi.ac.uk/cgi-bin/dbfetch) provides a generic interface to retrieve data entries given an identifier (Id or accession) from a wide range of biological databases available at EMBL-EBI. Two styles of URL can be used to access dbfetch:
The dbfetch documentation (http://www.ebi.ac.uk/cgi-bin/dbfetch) details the valid values for the database name ({DB}), data format ({FORMAT}) and data style ({STYLE}). The identifier list ({IDS}) is a comma separated list of entry identifiers. The identifiers can be either Ids, names or accessions. For example to retrieve the rat and mouse WAP proteins from UniProtKB:
For example fetching ADH1A_HUMAN from UniProtKB (examples/REST/libcurl/dbfetch_libcurl_get.c): /* Include libraries */ #include <stdlib.h> #include <string.h> #include <curl/curl.h> int main(int argc, char* argv[]) { /* Exit status to return */ int exitStatus = 0; /* Base URL for the service */ const char* baseUrl = "http://www.ebi.ac.uk/Tools/webservices/rest/dbfetch"; // Parameters for call const char* db = "UNIPROT"; const char* id = "ADH1A_HUMAN"; const char* format = "fasta"; /* Construct resource URL */ int urlLen = strlen(baseUrl) + strlen(db) + strlen(id) + 4; if(strlen(format) > 0) { urlLen += strlen(format); } char* url = (char*)malloc(sizeof(char) * (urlLen)); if(url == NULL) { printf("Error: unable to allocate memory for URL\n"); } strcpy(url, baseUrl); strncat(url, "/", 1); strncat(url, db, strlen(db)); strncat(url, "/", 1); strncat(url, id, strlen(id)); if(strlen(format) > 0) { strncat(url, "/", 1); strncat(url, format, strlen(format)); } /* Initialise libcurl */ curl_global_init(CURL_GLOBAL_ALL); char* curlErrStr = (char*)malloc(CURL_ERROR_SIZE); /* Get a curl handle */ CURL* curlHandle = curl_easy_init(); if(curlHandle) { curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, curlErrStr); /* Get resouce from URL and send to STDOUT */ curl_easy_setopt(curlHandle, CURLOPT_URL, url); CURLcode curlErr = curl_easy_perform(curlHandle); if(curlErr) { printf("%s\n", curl_easy_strerror(curlErr)); } /* Clean-up libcurl */ curl_global_cleanup(); } else { exitStatus = 1; } free(url); /* Return the exit status */ return exitStatus; } HTTP POSTWhile HTTP GET is great for retrieving information there are restrictions on the amount of data that can be sent using GET. Thus for transferring large amounts of data or complex parameters an alternative method has to be used. Since HTTP POST sends the data independently of the URL, POST is used in circumstances where complex or large data needs to be transferred. dbfetchThe dbfetch service accepts HTTP POST requests as well as HTTP GET requests, this is useful when using list of identifiers. For example fetching WAP_MOUSE and WAP_RAT from UniProtKB (examples/REST/libcurl/dbfetch_libcurl_post.c): /* Include libraries */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <curl/curl.h> int main(int argc, char* argv[]) { /* Exit status to return */ int exitStatus = 0; /* Endpoint for POST */ const char* endpointUrl = "http://www.ebi.ac.uk/cgi-bin/dbfetch"; // Parameters for call const char* db = "UNIPROT"; const char* id = "WAP_MOUSE,WAP_RAT"; const char* format = "fasta"; const char* style = "raw"; /* Construct resource POST data */ int postDataLen = strlen(db) + strlen(id) + 26; if(strlen(format) > 0) { postDataLen += strlen(format); } if(strlen(style) > 0) { postDataLen += strlen(style); } char* postData = (char*)malloc(sizeof(char) * (postDataLen)); if(postData == NULL) { printf("Error: unable to allocate memory for POST data\n"); } strcpy(postData, "db="); strncat(postData, db, strlen(db)); strncat(postData, "&id=", 4); strncat(postData, id, strlen(id)); if(strlen(format) > 0) { strncat(postData, "&format=", 8); strncat(postData, format, strlen(format)); } if(strlen(style) > 0) { strncat(postData, "&style=", 8); strncat(postData, style, strlen(style)); } /* printf("%s\n", postData); */ /* Initialise libcurl */ curl_global_init(CURL_GLOBAL_ALL); char* curlErrStr = (char*)malloc(CURL_ERROR_SIZE); /* Get a curl handle */ CURL* curlHandle = curl_easy_init(); if(curlHandle) { curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, curlErrStr); /* Set the endpoint to send the POST to */ curl_easy_setopt(curlHandle, CURLOPT_URL, endpointUrl); /* Specify the POST data */ curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, postData); /* Execute the POST, response goes to STDOUT */ CURLcode curlErr = curl_easy_perform(curlHandle); /* Report any errors */ if(curlErr) { printf("%s\n", curl_easy_strerror(curlErr)); } /* Clean-up libcurl */ curl_global_cleanup(); } else { exitStatus = 1; } free(postData); /* Return the exit status */ return exitStatus; } examples/REST/libcurl/dbfetch_libcurl_post.c.
1)
RFC1945 - Hypertext Transfer Protocol – HTTP/1.0 - http://www.faqs.org/rfcs/rfc1945.html
2)
RFC2616 - Hypertext Transfer Protocol – HTTP/1.1 - http://www.faqs.org/rfcs/rfc2616.html
3)
libcurl - http://curl.haxx.se/
![]() |