Hitting Github API REST with the Linux console
Updated: Jul 15
The very first step to hitting any API REST is to read the documentation because every API is a world. While some of them are very intuitive, others require a lot of time to think about how to make every single call due to the resource's format required. The Github API REST has calls requiring a very specific format of input parameters. Might be in the header, in the URL's path, as URL GET parameters, or inside a JSON formatted body. But this is not all, because the answer will also be returned as a body or as an HTTP code. So, It is better to get that documentation.
But what if your goal is to construct a curl call to manage every possible scenario? Well, that is what today's Teratip is all about. I'll give you the answer and then we'll walk through it.
function git_call() {
curl -s -w "{\"http_code\":\"%{http_code}\"}" -u ${1} \
-X "${2}" -H "Accept: application/vnd.github.v3+json" \
"https://api.github.com${3}" -d "${4}" | jq -s "."
}
This is a function you can copy and paste.
curl is the tool you will use. If you are not familiar with it yet, type man curl and you will see all this tool can do.
-s is to make the call silent. No progress bar nor any app output, but what comes from the call.
-w "{\"http_code\":\"%{http_code}\"}" This is a custom-made output that generates a JSON object with the HTTP code at the end of the body output. As you can see, it is manually formatted.
-u ${1} Github requires authentication. This is how you can send your token. To create one, go to github.com, log in, click your avatar -> settings -> Developer settings -> Personal access tokens, and create it from there. We’ll show you how to use it in a few seconds.
-X "${2}" The verb to be sent: GET, POST, DELETE, etc. Depends on the call.
-H "Accept: application/vnd.github.v3+json" To force the call's output to be JSON. This makes everything much easier.
"https://api.github.com${3}” The URL to hit to. The third parameter will be the construction of /user/repo/full_call_path. If you need to send GET parameters, you will need to add them manually to it, for example/repos/jim/myapp/pulls?state=open
-d "${4}" to send specific information JSON formatted. You can check this Teratip to learn how to create a perfect JSON on the console.
Now with all of this, you have two separated JSON objects created. One with the body output and another with the HTTP code. So you need to merge them in one single parseable response.
Piping the output to jq -s "." do that job. The -s parameter joins the two objects into one array.
And finally, we put everything inside one bash function. Just because we love bash functions and you can get any answer piping to jq. For example jq -Mr ".[1].http_code"
Examples
Example 1: Let's list the branches from a repository. The documentation is here: https://docs.github.com/en/rest/reference/repos#list-branches
To try it remember to replace $GIT_USER_TOKEN with your token
response=$(git_call "$GIT_USER_TOKEN" \
"GET" "/repos/tfutils/tfenv/branches" \
)
If everything went well, you’ll get a 200 when you type:
jq -Mr ".[1].http_code" <<<$response
If you have a different number, something went wrong.
Now you can get the branch names by doing:
jq -Mr ".[0][].name" <<<$response
Example 2: An example that returns an HTTP Code. Let’s delete a branch now:
To try this example, you need a larger configuration.
Besides replacing $GIT_USER_TOKEN with your own token, you need access to a branch you can delete, and replace ${USER}, ${REPO}, and ${BRANCH_NAME} with their values.
response=$(git_call "$GIT_USER_TOKEN" "DELETE" \
"/repos/${USER}/${REPO}/git/refs/heads/${BRANCH_NAME}"
)
Now you can write:
jq -Mr ".[].http_code" <<<$response
If you get 204, your branch has been deleted. If you have any other value, you will need to check the documentation to understand its meaning.
Example 3: Now one example that requires JSON data. Let’s retarget a pull request to the development branch. GIT_USER_TOKEN, USER, and REPO you already know. And PULL_REQUEST_NUMBER is described by itself.
response=$(git_call "$GIT_USER_TOKEN" "PATCH" \
"/repos/${USER}/${REPO}/pulls/${PULL_REQUEST_NUMBER}" \
'{"base": "development"}'
)
Check that it worked:
jq -Mr ".[1].http_code" <<<$response
200
and
jq -Mr ".[0].base.ref" <<<$response
development
Remember that REST API is always independent of the type of platforms or languages, therefore, it adapts to the type of syntax or platforms with which you are working. This offers great freedom when trying or changing new environments. The REST API can be called by PHP, Java, Python, Node.js, or like in this case, straight Bash.
However, it must be taken into account that the responses to requests are always made in the information exchange language using either XML or JSON. In this case, as Github recommends, JSON.
We hope this TeraTip helps you and you can integrate different APIs from Bash calls.
Suddenly you may be interested in Every format with its parser.
Juan Eduardo Castaño
DevOps Engineer
Teracloud