As you might be aware already, I’ve created a few blog posts on LoopBack that are mostly built on top of the Todo tutorial. It is because the main purpose of those blogs is to show how to add certain features, not the base application itself.
In this series of blog posts, I’m going to create an end-to-end application — a frontend application using React and an API layer with LoopBack that interacts with GitHub APIs. The intent is to go a bit in-depth on particular areas during the process, so if you’re new to LoopBack, I’d suggest you take a look at the Todo tutorial which is good for beginners.
What’s the application about?
In this application, I’d like to be able to do some reporting/metrics on a GitHub repo by calling some GitHub REST APIs and doing some manipulation. The whole application can be found in this repo.

In this blog
Within the LoopBack application, there are a few components involved — Controller, service proxy, DataSource and connectors.

In this blog, we are going to focus on accessing the GitHub APIs first. We are going to create a DataSource that connects to the GitHub APIs as shown in the diagram below. I’ll go through some of the details to configure the DataSource.

Before you begin
Scaffold the LoopBack application by using lb4 app
command. I normally keep all the default options.
Tip: You can simply run lb app <appName> --yes
. It will let you skip all the prompts!
Let’s get started!
Create a DataSource using lb4 datasource
command. Follow the prompts below:
$ lb4 datasource
? Datasource name: githubds
? Select the connector for githubds: REST services (supported by StrongLoop)
? Base URL for the REST service: https://api.github.ibm.com
? Default options for the request:
? An array of operation templates:
? Use default CRUD mapping: No
create src/datasources/githubds.datasource.ts
Let’s take a closer look at what we’ve selected in the prompt.
- Select the connector for githubds: Since we will be calling some GitHub REST APIs, so select
REST services
. Under the hood, this datasource will use the LoopBack REST connector to calls the GitHub APIs. If you’d like to learn more details about the configuration for this REST datasource, you can go to https://github.com/strongloop/loopback-connector-rest. - Base URL for the REST service: I think it’s self-explanatory.
- Default options for the request: This is about the options you can set for the request, e.g. header information. I prefer to leave it empty (by pressing Enter) because it’s easier to edit the options in the .ts file later.
- An array of operation templates: This refers to the operations you want the rest of the application to call. Again, I prefer to leave it empty for now.
Filling in the details — options
After running the CLI command, the config
in the DataSource file githubds.datasource.ts
should look something like:
const config = {
name: 'githubds',
connector: 'rest',
baseURL: 'https://api.github.ibm.com',
crud: false
};
We’re going to add the header information in the options
property that we’ve skipped previously. Add the following snippet inside the config
constant.
options: {
headers: {
accept: 'application/json',
Authorization: process.env.TOKEN,
'User-Agent': 'loopback4-example-github',
'X-RateLimit-Limit': 5000,
'content-type': 'application/json'
}
},
A few things to note here:
Authorization: process.env.TOKEN
: If you have any values like password and access token, you can set them as environment variables.'User-Agent': 'loopback4-example-github'
: When calling GitHub APIs, this is mandatory.
Filling in the details — operations
Within the operations
property, you can add a sets of template
and functions
. template
defines the API structure, whereas functions
defines the TypeScript functions that the rest of the application can call.
Add the snippet below inside config
constant which is at the same level as options
we just created.
operations: [
{
template: {
method: 'GET',
fullResponse: true,
url: 'https://api.github.com/search/issues?q=repo:{repo}+label:"{label}"'
},
functions: {
getIssuesByLabel: ['repo','label']
}
}, {
template: {
method: 'GET',
fullResponse: true,
url: '{url}'
},
functions: {
getIssuesByURL: ['url']
}
}, {
template: {
method: 'GET',
fullResponse: true,
url: 'https://api.github.com/search/issues?q=repo:{repo}+{querystring}'
},
functions: {
getIssuesWithQueryString: ['repo','querystring']
}
}
]
As you can see, there are 3 functions above:
- getIssuesByLabel: get the GitHub issues by specifying the GH org+repo and a label
- getIssuesByURL: you can pretty much call anything you want here. We might want to refine it later, but to save us some work, we leave it the way it is. I’ll show you later on why we have it this way (Hint: pagination!)
- getIssuesWithQueryString: get the GitHub issues by specifying the GH org+repo and query string. The “queryString” can be anything specified in the GitHub Search API.
Let’s take a closer look at the first set and see what we’re trying to do here:
{
template: {
method: 'GET',
fullResponse: true,
url: 'https://api.github.com/search/issues?q=repo:{repo}+label:{label}'
},
functions: {
getIssuesByLabel: ['repo','label']
}
}
url
: the{repo}
and{label}
represents the parameters for the url. Make sure that the functions have the matching parameter name.fullResponse
: I set it totrue
here because I need the response header to know if there are another pages of results I need to retrieve for GitHub API. Depending on APIs and your usage, you might just need to get the response body.headers
: there’s noheaders
in the above snippet. All GitHub API calls require the authorization token and other header info. But since we already have it at the top level, we don’t need to repeat here.
If you have other functions to add which is not using the same url “template”, you can add another set under operations
.
You can also find other properties for template
and more details: https://github.com/strongloop/loopback-connector-rest#defining-a-custom-method-using-a-template.
When it’s complete…
In the end, your config
constant should look the following:
What’s next?
In this blog, I went through the application overview and got into some of the details when creating a DataSource that can interact with the GitHub APIs. Next, we’re going to create a service proxy to expose those functions.