Tutorial

API Interfaces

This is one part of a multi part tutorial on getting started with a new application.

This tutorial covers:

  • creation and configuration of an API interface
  • mocking up API calls
  • TODO finish this list

To connect to an API, JCU Spark applications use API interfaces. An API Interface is an instance of a class descended from ApiInterface and registered with your app's Manager. The API Manager will create an instance of your API Interface when you need it.

What an API Interface is for

API interfaces exist to bundle knowledge about the API into a single place in your app's code. Inside your API interface you handle API-specific issues like what URLs to hit, how to handle errors, and manage data caching, sorting, paging, and issues like that. With those concerns managed in the API interface, you're freed up from having to handle them elsewhere in your app.

Write an interface

Create a file in src/interfaces called [ApiName]Interface, replacing the [ApiName] part with the name of your API. A simple API Interface with some mocked data looks like this:

import {ApiInterface} from '@jcu/spark'

export class WidgetInterface extends ApiInterface {
	static interfaceName = 'widget'
	static interfaceVersion = '1'
	static scopes = {
		WIDGE: 'urn:x-jcu-api:widgetapp:[ENV]:view'
	}

	async getWidgets() {
		const fakeData = {
			data: [
				{id: "widget1", size: 2},
				{id: "widget2", size: 7},
				{id: "widget3", size: 1}
			]
		}
		return this.delayedResult(fakeData)
	}
}

interfaceName and interfaceVersion are used to identify this interface when interacting with the API Manager, and for configuration.

scopes list the OIDC scopes this API will use (the string values of this data object are the actual scopes; the capitalised keys are just convenient shorter names you can use when working with scopes). The framework arranges things so that when your user logs in, all of the scopes across your app's API interfaces get requested.

getWidgets() is the single API function this interface makes avaialble to the rest of your app. In this case, we can expect this will return a list of widgets. This example uses the superclass's ApiInterface#delayedResult function to return a fake set of data. delayedResult simulates a network fetch, returning your mock data after a random delay of a few seconds (see the docs for more info).

Note that getWidgets() is an asynchronous function; getting stuff from a remote API takes time, so it will happen in the background.

Mock first

You should start your interface by writing mock methods in your API interface.

If your API provider isn't finished, it makes sense to mock up that API so you can get working on the front end. However even if your API is already written, I recommend mocking up an API as the first code you write in your app. This lets you solve the "how do I show my API data" interface question without having to also debug your API connections.

Configure an interface

You can't actually use an API interface until it get configured in your app's config file.

Open public/config, and find the apis key. configuration.apis is an array of API config objects. Add an entry for your API interface with name and version keys that match the name and version you used in your interface file. Also add a url key which points to the base URL of the API. If you're mocking out your API methods, you can make the URL an empty string.

It should look like this:

        "apis": [
            {
                "name": "widget",
                "version": "1",
                "url": "",
                "options": {}
            }
        ],

Register an interface

Now you have an interface and config for your interface, you just need to tell the API Manager about it. You do this by adding two lines to src/App.js.

Here's an excerpt from App.js with the two important lines indicated. The first imports your interface class, and the second adds that class to the API Manager.

import PageHome from './PageHome'
import {PageFirst} from './PageFirst'
import {PageSecond} from './PageSecond'

import {TestInterface} from './interfaces/TestInterface'
import {WidgetInterface} from './interfaces/WidgetInterface' # <=== 1. IMPORTING API INTERFACE

const navItems = [
	{label: 'Home', target: '/'},
	{label: 'First', target: '/first'},
	{label: 'Second', target: '/second'}
]

ApiManager.addInterface(TestInterface)
ApiManager.addInterface(WidgetInterface) # <=== 2. REGISTERING API INTERFACE

function App() {

With this complete, you're now ready to use your interface.


<< Previous Next >>
Customising The Template Handling Data