Making API requests

πŸ“˜

If you're just looking to fetch resource data, please have a look at the ResourceDataClient first. In most cases, there will be a selector available for the resource data you need and it'll give you lots of extra benefits over just making your own API requests.

URLs

To get an API URL you can use the getApiUrl(rel, params) method found on the ComponentContext instance. It will return the URL for any API rel that can be found in the API Discovery and it allows for replacing URL or query parameters via a params object.

let url;

url = context.getApiUrl('VpnUsage')
console.log(url);
// result: "https://portal.ixon.cloud:443/api/vpn-usage"

url = context.getApiUrl('Agent', { publicId: 'ixrouter0001' });
console.log(url);
// result: "https://portal.ixon.cloud:443/api/agents/ixrouter0001"

url = context.getApiUrl('Agent', { publicId: 'ixrouter0001', fields: 'name,publicId' });
console.log(url);
// result: "https://portal.ixon.cloud:443/api/agents/ixrouter0001?fields=name,publicId"

Headers

On all API requests the Api-Application header is required and for most requests you'll also need an Authorization and Api-Company header. The necessary information to supply these header values can be found on the component context's AppData object.

Example

The example below is based on a possible situation where there is a PLC behind the router that runs an HTTP server which serves a JSON API that has a GET /json-api/v1/logs endpoint. The code example makes use of JavaScript's Fetch API for making HTTP requests.

<template>
  <button @click="readLogs()" :disabled="!server">Read Logs</button>
  <ul v-if="logs">
    <li v-for="log in logs">
      {{ log.text }}
    </li>
  </ul>
</template>

<script>
export default {
  name: 'log-reader',
  props: ['context'],
  data() {
    return { baseUrl: null, logs: null, server: null };
  },
  methods: {
    async readLogs() {      
      if (!this.baseUrl) {
        const url = this.context.getApiUrl('WebAccess');
        const response = await fetch(url, {
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + this.context.appData.accessToken.secretId,
            'Api-Application': this.context.appData.apiAppId,
            'Api-Company': this.context.appData.company.publicId,
            'Api-Version': '2'
          },
          body: JSON.stringify({ server: { publicId: this.server.publicId } }),
          method: 'POST',
        })
        .then(res => res.json())
        .catch(error => {
          console.error('Error:', error);
        });
        
        if (response) {
          await fetch(response.data.url, { credentials: 'include' });
          this.baseUrl = response.data.url.slice('/?')[0];
        }
      }
      
      if (this.baseUrl) {
        this.logs = await fetch(this.baseUrl + '/json-api/v1/logs')
          .then(res => res.json())
          .catch(error => {
            console.error('Error:', error);
          });
      }
    }
  },
  created() {
    const client = this.context.createResourceDataClient();
    
    // Queries the "active device" on this page to find its HTTP server
    client.query({
      selector: 'Agent',
      fields: ['servers.publicId', 'servers.type']
    }, result => {
      this.server = result[0].data.servers.find(server => server.type === 'http');
    });
  }
};
</script>

<style scoped></style>