Edge APIs

Overview

The purpose of this page is to serve as a collection point for high level information about edge APIs.  

Motivation

The role of edge APIs is primarily to fulfill three functions:

  1. Provide simplified (API key-based) auth mechanism allowing interactions with external systems to perform both auth and business logic in a single API call.

  2. Provide an isolation layer between external systems and backend FOLIO modules which sometimes (frequently?) make breaking contract changes.

  3. Provide translations (e.g. json -> xml, etc.) or other adaptations to "bridge the gap" between technologies/protocols/formats/etc. used by external systems and those used by FOLIO.

Authentication

Edge modules provide a simplified authentication mechanism which allows external systems to integrate with FOLIO w/o needing to be changed. Authentication into FOLIO happens in the following ways:

  1. password flow - a user provides username and password, and gets back an access (okapi) token.  That token is then provided in subsequent calls to FOLIO APIs for entitlement and authorization purposes.

  2. SAML2.0 - the user authenticates with an Identity provider (IdP), and then gets back an access (OKAPI) token.  Again that token is then provided in subsequent calls to FOLIO APIs for entitlement and authorization purposes. (This is a simplified description, but makes the point.)

In both cases, it's a two step process... Step#1, authenticate, Step#2 interact with FOLIO using the token obtained in the first step.

Many legacy systems do not support these auth flows, hence a need for Edge APIs.

It is common for these external systems to support the ability to specify a request header, query argument, etc. when calling the ILS.  So API key authentication was a natural fit since the API key can be provided in either of those ways.

Isolation

Another concern with external system integrations is the API contracts themselves.  Breaking API changes are made in FOLIO all the time; the FOLIO community must coordinate those contract changes across development teams/modules/etc.

However, that level of coordination and adjustment is not practical in the case of external systems.  Even in the best case it means making configuration adjustments in those external systems.  In other cases it might mean making code adjustments in codebases which we don't control or otherwise have access to.

Edge APIs mitigate this problem by serving as an effective isolation layer.  The outward-facing contract between external systems and the edge APIs does not change often, and if it does the changes will be backwards compatible. In several cases, these outward-facing contracts are governed by standards bodies and are much more stable by their nature. The contracts on the FOLIO side may change.  In this case FOLIO controls both sides of the equation (edge api + backend module).

Translations

Finally, edge APIs provide translations, format conversions, or other adaptations to bridge the gap between external systems conventions/technologies/protocols/formats and those used in FOLIO.  Not all systems know how to consume FOLIO's messages directly, but do know how to consume some set of well-defined messages.

Examples

  • RTAC offers up live circulation data to discovery layers in a way that insulates them from internal change to FOLIO APIs

  • The GOBI edge module provides a way to place orders in FOLIO with a similar degree of insulation

  • NCIP and SIP2 illustrate all three of these points, they have different authentication mechanisms, use non-JSON protocols (XML or text), and provide a standards-oriented way for external systems to perform circulation-related actions in FOLIO

  • Z39.50/SRU, though not using the edge module frameworks, also illustrates these points: typically on open Web with no authentication, protocols are either in 

    the ASN.1/BER message format (Z39.50) or the XML (SRU), and they expose a standard search interface to the outside world.

Frameworks

Multiple frameworks have been developed to aid in the creation of edge APIs.   These frameworks handle many of the tasks which need to be performed by almost all edge APIs, thereby reducing the amount of code duplication and making it easier to maintain the edge APIs themselves.

edge-common Framework

The intent of edge-common is to simplify the implementation of edge APIs by providing much of the boilerplate code shared among these APIs.

Github: https://github.com/folio-org/edge-common

The README found at the link above contains general information that applies to many of the edge APIs, including the following topics:

  • Dependency management

  • API Keys: sources, format and generation

  • Institutional users and secure storage of credentials

  • Configuration

edge-common-spring Framework

The edge-common framework has been ported to the "spring" stack (aka the "spring way").  See the README for more information.

Github: https://github.com/folio-org/edge-common-spring

Existing APIs

A list of existing edge APIs and related information/links.

edge-rtac 

Edge API to interface with FOLIO for 3rd party discovery services to determine holdings availability.

Github: https://github.com/folio-org/edge-rtac

API Documentation: https://dev.folio.org/reference/api/#edge-rtac

Other wiki documentation: What gets returned in edge-rtac response

Diagram

Demos/Presentations

Sprint Review 36-39 @ ~1:07:10 (Demo)
https://drive.google.com/file/d/1xidmMs3anoB0SK1DYPOqMEp6CP2wpZIL/view

edge-patron

Edge API to interface with FOLIO for 3rd party discovery services to allow patrons to perform self-service actions (place holds, renewals, etc)

Github: https://github.com/folio-org/edge-patron

API Documentation: https://dev.folio.org/reference/api/#edge-patron

Diagram

Demos/Presentations

Sprint Review 40/41 @ 58:00 (Demo - Account Info)
https://www.youtube.com/watch?v=nhNdlyCMZVg

Sprint Review 42/43 @ 1:13:00 (Demo - Loans/Fees & Fines)
https://www.youtube.com/watch?v=xhHWmFKp2mY

edge-orders

The purpose of this edge API is to bridge the gap between 3rd party purchasing systems/vendors and FOLIO. More specifically, the initial implementation was built with EBSCO's GOBI (Global Online Bibliographic Interface) service in mind, though the aim was to make a general-purpose edge API that will work with other vendors as well.

Github: https://github.com/folio-org/edge-orders

API Documentation: https://dev.folio.org/reference/api/#edge-orders

Diagrams

Demos/Presentations

Sprint Review 42/43 @ ~1:14:40 (Overview)
https://www.youtube.com/watch?v=xhHWmFKp2mY

Sprint Review 46/47 @ ~20:10 (Demo)
https://www.youtube.com/watch?v=kVt84MFyUxM

Vendor Integrations

Edge-orders is designed to support multiple vendors.  Currently, adding a new vendor requires:

  • Writing a vendor-specific module (see above) this is where mapping and translation happens between the vendor and FOLIO (mod-orders).  Lookups of things like locations, material-types, organizations, etc. will also happen here.

  • Minor changes in edge-orders to handle proper routing of requests to the proper vendor-specific module (e.g. mod-gobi, mod-ebsconet, etc.).  There's essentially a decision tree that looks at the "type" query argument in the request and uses that to proxy the request to the appropriate API, e.g. POST /orders?type=GOBI proxies the request to POST /gobi/orders. 

    • One way to make this easier would be to allow for these type → API mappings to be defined via configuration.  See EDGORDERS-TBD.

JIRA

edge-oai-pmh

Edge API for Metadata Harvesting (OAI-PMH Version 2.0)

Github: https://github.com/folio-org/edge-oai-pmh

API Documentation: https://dev.folio.org/reference/api/#edge-oai-pmh

Diagram

Demos/Presentations

Sprint Review 50/51 @ 16:15
https://www.youtube.com/watch?v=wrXxqcCPZx4

edge-sip2

Edge API for SIP2 (Standard Interchange Protocol Version 2.0) integration with a Self Check (SC) station. This edge module is unlike the other edge modules due to the fact that SIP2 uses TCP for message interchange. Once the SC is connected to edge-sip2, SIP2 messages are decoded and translated to existing FOLIO API messages. The FOLIO responses are encoded as SIP2 messages and delivered to the SC. Typically the SC will allow the patron to check out an item, check in an item, place a hold on an item, renew an existing loan and pay fees and fines they owe.

Github: https://github.com/folio-org/edge-sip2

API Documentation: https://dev.folio.org/reference/api/#edge-sip2

Diagram

edge-ncip

The purpose of this module is to expose mod-ncip to external applications/3rd party software. It simply passes requests through to the NCIP module (after the API key is authenticated). It does not contain any other functionality.

Github: https://github.com/folio-org/edge-ncip

API Documentation: https://github.com/folio-org/mod-ncip

edge-inn-reach

Connecting an InnReach Central Server.

GitHub: https://github.com/folio-org/edge-inn-reach

API Documentation: https://dev.folio.org/reference/api/#edge-inn-reach

edge-caiasoft

Connecting a CaiaSoft remote storage provider.

GitHub: https://github.com/folio-org/edge-caiasoft

API Documentation: https://dev.folio.org/reference/api/#edge-caiasoft

edge-dematic

Connecting a Dematic remote storage provider.

GitHub: https://github.com/folio-org/edge-dematic

API Documentation: https://dev.folio.org/reference/api/#edge-dematic

edge-lti-courses

This edge module acts as an LTI Tool Provider to connect learning management systems (LMS) such as Sakai and Blackboard (LTI Platforms) to FOLIO via the Learning Tools Interoperability (LTI) Advantage protocol to share the course reserves stored in FOLIO.

GitHub: https://github.com/folio-org/edge-lti-courses

API Documentation: https://dev.folio.org/reference/api/#edge-lti-courses

edge-connexion

Serves OCLC Connexion requests.

GitHub: https://github.com/folio-org/edge-connexion

API Documentation: n/a

Reference Environments

The APIs above are deployed to the following reference environments:

See https://dev.folio.org/guides/automation/ for additional details

folio-snapshot

Build from HEAD/master nightly.

Base URL:  https://folio-snapshot.dev.folio.org:8000

Example Request (edge-orders): 

curl 'https://folio-snapshot.dev.folio.org:8000/orders?type=GOBI' \ -H 'Authorization: apikey eyJzIjoiNXNlNGdnbXk1TiIsInQiOiJkaWt1IiwidSI6ImRpa3UifQ==' \ -H 'Content-Type: application/xml' \ -XPOST \ -d '<PurchaseOrder> <CustomerDetail> <BaseAccount>8910</BaseAccount> <SubAccount>891010</SubAccount> </CustomerDetail> <Order> <ListedPrintMonograph> <collection> <record> <leader>00000nam a2200000u 4500</leader> <controlfield tag="001">99974828471</controlfield> <controlfield tag="003">NhCcYBP</controlfield> <controlfield tag="005">20180905153857.0</controlfield> <controlfield tag="008">180905t20112011xx |||||||||||||| eng d</controlfield> <datafield tag="020" ind1=" " ind2=" "> <subfield code="a">9780547572482</subfield> <subfield code="c">14.95</subfield> </datafield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="a">(OCoLC)717297695</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">DICK, PHILIP K</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">MAN IN THE HIGH CASTLE.</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">BOSTON</subfield> <subfield code="b">MARINER BOOKS</subfield> <subfield code="c">2011</subfield> </datafield> </record> </collection> <OrderDetail> <FundCode>USHIST</FundCode> <Location>KU/CC/DI/A</Location> <Quantity>2</Quantity> <YBPOrderKey>99974828471</YBPOrderKey> <OrderPlaced>2018-09-05T15:38:55</OrderPlaced> <Initials>Mark</Initials> <ListPrice> <Amount>14.95</Amount> <Currency>USD</Currency> </ListPrice> <NetPrice> <Amount>13.16</Amount> <Currency>USD</Currency> </NetPrice> <LocalData> <Description>LocalData1</Description> <Value>Book</Value> </LocalData> <LocalData> <Description>LocalData2</Description> <Value>Notify requester upon receipt</Value> </LocalData> <LocalData> <Description>LocalData3</Description> <Value>Anne Esterhazy</Value> </LocalData> <LocalData> <Description>LocalData4</Description> <Value>signed-edition,vip-order</Value> </LocalData> </OrderDetail> </ListedPrintMonograph> </Order> </PurchaseOrder>'