Passer au contenu principal

Adaptateurs

Un adaptateur est un module Javascript open-source qui fournit aux utilisateurs principaux d'OpenFn core un ensemble d'opérations qui aident à communiquer avec un système externe spécifique. Dans le passé, nous les appelions souvent « paquets linguistiques ». On utilise parfois les deux termes de manière interchangeable, mais la meilleure façon de communiquer sur les adaptateurs est la suivante :

  • « Quel adaptateur ce job utilise-t-il ? » (« Ce job utilise language-dhis2. »)
  • « L'adaptateur DHIS2 est appelé language-dhis2. »
  • "Je n'ai pas l'adaptateur approprié pour ce job, laissez-moi l'installer en exécutant npm install @openfn/language-dhis2.

En bref, la plupart des adptateurs suivent la convention de dénomination @openfn/language-xyz, mais pas tous !

Où les trouver ?

Sur Github

Les adaptateurs développés peuvent être trouvés dans GitHub sous https://github.com/openfn, en commençant par le préfixe language-xyz. Voici quelques exemples :

Sur la plateforme

Lors de la création ou de la modification d'un job sur la plateforme, vous pouvez choisir l'adaptateur pour exécuter le job. De cette façon, vous « importez » les opérations nécessaires. Ouvrez simplement la liste déroulante des adaptateurs, et cliquez sur l'un d'entre eux.

Sur npm

La plupart de nos adaptateurs sont également disponibles sur npmjs.

Liste des adaptateurs dans npm

Install on platform via npm

When using platform, you can install adaptors that are not part of the recommended adaptors picklist directly from npm.

To install from npm, click on the cloud download icon next to the adaptor version picklist. In the Select Unreleased Adaptor dialog box, enter the adaptor name(e.g. dhis2 for language-dhis2) and the corresponding version number(e.g. v2.3.4), as listed on npmjs, for the adaptor of your choice. The platform will attempt to install the selected adaptor version it can be used to run the specified job.

Note that, after this custom installation of the adaptor, platform will not add this adaptor version to the picklist of recommended adaptors in JobStudio, but you are guaranteed that the adaptor will be available to use in any of your jobs as long as you specify it via the Select Unreleased Adaptor dialog.

Developing adaptors

You can develop a new adaptor from scratch or extend an existing one.

Extension d'un adaptateur

Extending an adaptor equals adding one or multiple new operations. The new operations can be added inside the src/Adaptor.js file of the adaptor.

Développement d'un nouvel adaptateur

Developing a new adaptor can be done by cloning the template available here via the USE THIS TEMPLATE button over on Github.

Use this template button

Opération par défaut

This template contains a default create operation that can be customized according to the objectives of the new adaptor.

export function create(path, params, callback) {
return state => {
// expand references for the data argument with state
// do the work
// return state
};
}

Considérations générales

Using @openfn/language-common.http

In many cases, it's useful to be able to execute regular HTTP requests inside a specialized adaptor (e.g. posting the output of a Primero case fetch to an OpenFn inbox). Considering these types of situations, language-common implements and exports an http module. To use http in any job executed with a specific adaptor consider exporting it directly from language-common.

...
export {
alterState,
...
http,
...
sourceValue,
} from '@openfn/language-common';

Import language-common from npm

To leverage the last tested available version of our language-common adaptor, consider importing the one published in npm through @openfn/language-common.

Accordingly, your package.json should add a dependency to that version as this (snippet taken from language-postgresql):

{
"dependencies": {
"@openfn/language-common": "1.2.6",
"pg": "^8.3.2",
"pg-format": "^1.0.4"
},
...rest
}

Construire et Tester

Construire

Building an adaptor for release is done by running the command npm run build from the root folder.

Tests

Tests can be written with nock under the path test/index.js.

describe('createPatient', () => {
before(() => {
nock('https://fakepatient.server.com')
.post('/api/patients')
.reply(200, (uri, requestBody) => {
return { ...requestBody, fullName: 'Mamadou', gender: 'M' };
});
});

it('makes a post request to the patient endpoint', async () => {
const state = {
configuration: {
baseUrl: 'https://fakepatient.server.com',
username: 'hello',
password: 'there',
},
data: {
fullName: 'Mamadou',
gender: 'M',
},
};

const finalState = await execute(
create('api/patients', {
name: dataValue('fullName')(state),
gender: dataValue('gender')(state),
})
)(state);

expect(finalState.data).to.eql({
fullName: 'Mamadou',
gender: 'M',
});
});
});

Run your tests with npm run test. Tests are written to assess dummy calls on the available helper functions.

 ~/devtools/adaptors/adaptor > npm run test

> language-template@1.0.0 test /home/taylor/devtools/adaptors/adaptor
> mocha --require @babel/register



execute
✓ executes each operation in sequence
✓ assigns references, data to the initialState

create
✓ makes a post request to the right endpoint
✓ throws an error for a 404
✓ handles and throws different kinds of errors

createPatient
✓ makes a post request to the patient endpoint


6 passing (16ms)

~/devtools/adaptors/adaptor >

When writing tests, bear in mind as well for scenarios that could trigger errors.

describe('create', () => {
before(() => {
nock('https://fake.server.com')
.post('/api/noAccess')
.reply(404, (uri, requestBody) => {
return { detail: 'Not found.' };
});

it('throws an error for a 404', async () => {
const state = {
configuration: {
baseUrl: 'https://fake.server.com',
username: 'hello',
password: 'there',
},
};
const error = await execute(create('api/noAccess', { name: 'taylor' }))(
state
).catch(error => {
return error;
});
expect(error.message).to.eql('Request failed with status code 404');
});

});