Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 29 Current »

The SHELL adapter library is just intended to something you copy and rename and make it into a real adapter for a real system. It has all the boiler plate you need. I made it because I wanted to try to build a few adapters to Solve the calendar management problem.

I took the Slack Notifier Adapter and hollowed it out to make this empty adapter. Should help me write a few adapters fast (remove bottlenecks )

The shell adapter ships with Iguana just add the Shell Example - see Create a Component .

So how do we use it say to create an Atlassian adapter.

 A good adapter is a library showing how to connect to a system

In Iguana X, an open system, we provide adapters as libraries to connect with various applications. These adapters are intentionally designed to be simple and intuitive, making them easily extendable by users to meet their specific needs. This approach contrasts with the complexity often found in open-source projects and the rigidness of complete platforms like Zapier. Iguana's inclusive environment, featuring a Translator, logging, queuing system, and dashboard, though convenient, requires users to invest effort in learning. Our goal is to empower users with adaptable tools, understanding that no adapter can be universally complete.

See:

 Typically we have an example component which just shows the usage of the library

The component aims to showcase the library's use, easing the learning process for users to integrate with systems efficiently. It's crafted to enable customers to quickly start without delving deep into documentation or seeking iNTERFACEWARE staff help. Therefore, it doesn't cover every detail of the problem but rather provides a clear direction, setting customers on their own path of exploration and discovery.

 Adapters will typically be created with the authentication parameters without hardcoded custom fields.

These parameters should not be hard coded into things like custom fields. This is because our customers may use these adapter libraries in components with others.

 Often we layer in a 'custom method' which has all the boiler plate code for an say a web API

For each adapter, we create a custom method to avoid the need for a lot of copy-pasted code. This method contains all the essential code for connecting to a web API, eliminating the repetition of the same code for different API methods. We have one main custom method, with other specific APIs serving as wrappers around it. If we need to access an API method for which we haven't created a specific wrapper, we can simply call this custom method, specify the API path, and provide any necessary parameters. This approach makes using new API methods straightforward and minimizes the need for additional setup.

 We create a few specific method wrappers for calls that typically use the 'custom method'

Each specific call does not typically have much code because most of the 'boilerplate' code is in the custom method, and it's nice that each of these methods has help. Doing things this way should make it quite clear to a user how they can extend each adapter.

See Setting up help for an object with methods

 Have some general comments about the nature of the API

Comments should be concise and straightforward, guiding users on what to do next with the API. For example, in systems like Pipedrive where custom fields use GUIDs, good documentation would explain how to address this issue. The aim is to educate users, not overwhelm them by attempting to solve every problem.

Implementation Approach:

 Start with a copy of new Custom component

Let’s use a copy of new Custom component (Create a Component ) and name it ‘Confluence adapter’

 Import the SHELL library and associate it with a new repo
 Rename the Library folder and all the files in it to a new prefix

For instance:

 Search and replace SHELL for ATTL in the project

This gets all the prefixes consistent.

 Make sure the ATTLclient function gets the parameters needed to authenticate
function ATTLclient(T)
   local S= {}
   setmetatable(S, MT)
   S.key = T.key
   return S
end

So in the case of Atlassian we need:

  • user - I.e. fred.smith@interfaceware.com

  • space - i.e. ABC for a Confluence space that has this ID

  • key - A unique personal API key for a confluence user

  • organization - to construct base URL to our Confluence space, e.g. https://acme.atalassian.net

This adheres with Naming convention for table parameters in Iguana.

These should just be passed through in the table arguments. So the code becomes:

function ATTLclient(T)
   local S= {}
   setmetatable(S, MT)
   S.key           = T.key
   S.space         = T.space
   S.user          = T.user
   S.organization  = T.organization
   return S
end
 Add API access key to this project

The API access key needs to be treated as password. Thus we create in config.json a custom field named ‘key' of type 'Password’ and store in it the personal Atlassian API access key, respective to the user name in use.

 Implement a good custom method

The custom method should do most the guts of the adapter. Most web APIs have some magic sauce that you have to make an API call. The custom method does this and should make it easy to call methods on the API which have not been wrapped explicitly.

Let’s call our new Custom method ATTLdescendants. We can rename ATTLhello into ATTLdescendants and to rewrite its content.

This method will help us to invoke the API method ATTLgetDescendants.

 Implement a good API method

Let’s call our new API method ATTLgetDescendants. We can rename ATTLcustom into ATTLgetDescendants and to rewrite its content.

This method will returns all pages in a space.

 More about API methods

Sometimes an API method would require a parameter which can be discovered only programmatically. In our example of Confluence Adapter this is Confluence Space Id parameter, which isn’t the same as a Space Key above.

The API method ATTLgetSpaceId will help us to discover this value. Let’s create new Lua file, name it ATTLgetSpaceId and write its content.

 Update Client Constructor

Append to Client’s meta table the three newly added methods and the ‘space_id’ variable declaration

local MT={}

MT.__index = {}
MT.__index.descendants     = require 'ATTL.ATTLdescendants'
MT.__index.getSpaceId      = require 'ATTL.ATTLgetSpaceId'
MT.__index.getDescendants  = require 'ATTL.ATTLgetDescendants'

help.map{dir='ATTL/help',methods=MT.__index}

function ATTLclient(T)
   local S= {}
   setmetatable(S, MT)
   S.key           = T.key
   S.space         = T.space
   S.user          = T.user
   S.organization  = T.organization
   S.space_id      = T.space_id
   return S
end
 Not to forget the Help files

Add Help files to explain what parameters the methods expect. Other users will appreciate this!

image-20240319-153543.png
 Time to put all of this to good work

Let’s create a simple main.lua file

require "ATTL.ATTLclient"

A = ATTLclient{
   key          = component.fields().key,
   space        = 'EC',
   user         = 'fred.smith@interfaceware.com',
   organization = 'interfaceware'
} 

function main(Data)
   A:getSpaceId() 
   local count = 2 
   A:descendants{count = count, live = true}
end
 How does this main.lua work?

Right after declaration of Client instance and passing the parameters to it, we discover the Confluence Space ID. This value couldn’t be known without running this API call.

Next we prepare for paginated API call and require only 2 calls to be executed by setting ‘count’ variable to number 2. This will save the time while testing. The parameters for this method are described in respective help file.

And finally, we request from API to return the listing of descendants for 50 pages.

image-20240319-154423.png
 Share a little of 'what is next'?

So, we can query Atlassian API for Confluence! What it is good for? We can query documents, we can edit documents, we can modify/export/add/delete content in any manner we imagine. The complete documentation for this API is available here.

Just create more API methods and more Custom methods.

Custom methods are very helpful to keep the API methods true to vendors API documentation. Custom methods will help to create your specific parameters combination, and to massage the responses. Custom methods are the interface, between your code to clean and true API methods.

  • No labels