Shared logic implementation for calling an EVA service

Downloads in past


3.5.105 months ago3 years agoMinified + gzip package size for @springtree/eva-sdk-core-service in KB


This library provides access to EVA endpoints and services. Any services defined in the service registry can be called on an endpoint. EVA endpoints need to be bootstrapped once for their basic configuration details.


EVA Endpoint

import { bootstrapEndpoint } from '@springtree/eva-sdk-core-service';

// This is the recommended way to get a bootstrapped endpoint
// If the endpoint was bootstrapped before it will not do so again unless
// you specifically want to
const evaEndpoint = await bootstrapEndpoint( { uri: 'https://eva.newblack.io' } );

// You can ask a bootstrapped endpoint for its basic data
const applicationConfiguration = endpoint.getApplicationConfiguration();

You can also bypass the bootstrap cache:
import { EvaEndpoint } from '@springtree/eva-sdk-core-service';

// You can also create an endpoint instance and bootstrap it yourself
// which will bypass the cache entirely
const evaEndpoint = new EvaEndpoint( 'https://eva.newblack.io' );
await evaEndpoint.bootstrap();

EVA Service registry

The EVA service registry contains all available services. You can instantiate an EvaService with a service definition from the registry and a bootstrapped EvaEndpoint. A number of service registries exist for various purposes. The core service registry is the one required for the bootstrapping to function. The core service registry will be needed by most if not all EVA client applications.
import { bootstrapEndpoint } from '@springtree/eva-sdk-core-service';
import { Core } from '@springtree/eva-services-core';

const evaEndpoint = await bootstrapEndpoint( { uri: 'https://eva.newblack.io' } );

// The easiest way is to call a service directly on the endpoint
const serviceResponse = await endpoint.callService(Core.GetOrder);

// You can provide the request payload and service call options as well
const serviceResponse = await endpoint.callService(
  { Username: 'admin', Password: 'secret' },
  { timeout: 30000 },

// If you need access to the EvaService instance and do not want to call immediately
// you can also prepare a service call
const service = await endpoint.prepareService(Core.GetOrder);
const result = await service.call({ ID: 1 });

Advanced usage

You can also use the EvaService class directly using the createServiceDefinition factory method from the core services registry.
import { bootstrapEndpoint} from '@springtree/eva-sdk-core-service';
import { Core} from '@springtree/eva-services-core';

const evaEndpoint = await bootstrapEndpoint( { uri: 'https://eva.newblack.io' } );

const getOrder = new EvaService<Core.GetOrder>(

// If a service requires a payload be sure to set it before calling it
getOrder.data.request = { ... };

// You can reuse this service instance but every call will overwrite any
// previous response
const serviceResult = await getOrder.call();

// You can access response through the EvaService class or from the promise
// The request you used is also still available
console.log( 'response', serviceResult.response );
console.log( 'response', getOrder.data.response );

Error handling

There are different types of errors that can occur. We can fail to make a call or the call might return an error response.
import ky from 'ky-universal';

try {
  const serviceResult = await getOrder.call();
} catch (error) {
  if (error instanceof ky.HTTPError) {
    // An HTTP response error (non 2xx/3xx) or
    // an Error/Authentication failure was detected in the payload
    const httpError: ky.HTTPError = error;
    const jsonError = await httpError.response.json();
    console.error('Error response', jsonError);
  } else if (error.name === 'AbortError') {
    // Fetch abort controller was used
    console.warn('Call was aborted');
  } else {
    // Any other error
    console.error('An error occurred', error);

Custom EVA service

If a service has not been added to the curated service registry you can create a service instance using the types from @springtree/eva-core yourself.
import { bootstrapEndpoint, IEvaServiceDefinition } from '@springtree/eva-sdk-core-service'

const evaEndpoint = await bootstrapEndpoint( { uri: 'https://eva.newblack.io' } );

// By using a class you can define your own service once and then instantiate
// it multiple times to make an actual request
class MyService implements IEvaServiceDefinition {
  path = '/api/core/MyService';
  request?: EVA.Core.Services.MyService;
  response?: EVA.Core.Services.MyServiceResponse;

const myService = new EvaService<MyService>(
  new MyService(),

// Set a typed request payload
myService.setRequest( { ... } );

await myService.call();

console.log( 'response', myService.data.response );

// If no typings are present you can also declare them locally or use any
class MyExperimentalService implements IEvaServiceDefinition {
  path = '/api/core/MyExperimentalService';
  request?: any;
  response?: any;

Major updates

v3.0.0 has removed the default token and application list support (deprecated)
v2.0.0 changed the XHR library from Axios to Ky