Skip to content

KC3 API Best Practices

DCPPC-DRAFT-#: 9

DCPPC-DRAFT-Title: DCPPC API Best Practices

DCPPC-DRAFT-Type: Informational

Point of Contact: Michel Dumontier

Email of Point of Contact: michel.dumontier@maastrichtuniversity.nl

Submitting Team: KC3

Requested DCPPC-DRAFT posting start date: 09/07/2018

Date Emailed for consideration: 09/07/2018

DCPPC-DRAFT-Status: Active and open for comment

URL Link to this Document: https://docs.google.com/document/d/13uIxXZf2Cq7zgB2XOcph1dU2rK8sg-W8GK1zqfIaoY0/edit?usp=sharing

License: This work is licensed under a CC-BY-4.0 license.

Purpose

This document summarizes DCPPC API best practices for the NIH-DCPPC and extended community and requests discussion and suggestions for improvement.

Compliance

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

An implementation is not compliant if it fails to satisfy one or more of the MUST or REQUIRED level requirements for the protocols it implements. An implementation that satisfies all the MUST or REQUIRED level and all the SHOULD level requirements for its protocols is said to be "unconditionally compliant"; one that satisfies all the MUST level requirements but not all the SHOULD level requirements for its protocols is said to be "conditionally compliant."

Introduction

An Application Programming Interface (API) is a computer-accessible interface to perform a set of operations by an external user. Here, we focus on best practices for Web APIs, also known as web services, with particular attention to those APIs that use the Hypertext Transfer Protocol (HTTP) as a communication protocol, using a variety of architecture styles such as Representational State Transfer (REST) to manipulate web resources, and can define the structure of the request and response message, which is usually in JavaScript Object Notation (JSON), Extensible Markup Language (XML), or syntactic representations of the Resource Description Framework (RDF) such as N-Triples or Turtle (TTL).

The smartAPI project (http://smart-api.info) is an initiative to maximize the quality of API metadata so as to make them more FAIR (Findable, Accessible, Interoperable, Reusable). The smartAPI project extends a global web API documentation standard called the OpenAPI (http://openapis.org; formerly swagger), with additional metadata requirements, fields and value sets. These metadata can then indexed to facilitate discovery of an API by literal, operation, or by input/output data types. The BioThings Explorer (http://biothings.io/explorer/) is one implementation of an application that uses the smartAPI registry of web services to enable users to discover and invoke smartAPIs, as well as explore connections between them.

DCPPC API Best Practices

We make the following recommendations to make web APIs Findable, Accessible, Interoperable, and Reusable (FAIR [1]):

  1. The Web API MUST have a valid smartAPI-compliant document. The smartAPI document can be hand crafted using the smartAPI editor, or automatically generated from in-code annotations (see Appendix). While the smartAPI is best for REST-style APIs with JSON messages, other APIs such as query APIs like GraphQL and SPARQL can also be documented with respect to the documentation and the query endpoint. To mark the API as being associated with the NIH Data Commons, include a Tag with name “NIHdatacommons”.

  2. The smartAPI document MUST be added via its URL to the smartAPI registry. This means that the document must be web-accessible. We recommend that the document is placed in a GitHub repository with the code for the web API.

  3. All parameters and operations published in the SmartAPI registry MUST function as documented.

  4. API methods MUST be implemented as HTTP/1.1, HTTP/2 methods (in accordance with https://tools.ietf.org/html/rfc2616, https://tools.ietf.org/html/rfc7540) and MUST return status codes (in accordance with https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)

  5. The API SHOULD

    1. Use shared and resolvable identifiers. Shared identifiers are identifiers that are drawn from a clearly stated and registered identifier scheme (e.g. in identifiers.org). API requests and responses should use these identifiers to identify contained entities, their attributes and their relations. Using shared identifiers will act to reduce the user burden of data integration from multiple data sources. Resolvable identifiers are those identifiers that can be directly (without external knowledge) be used obtain information about the resource with the identifier. We recommend the use of URLs.

    2. Use shared vocabularies to describe objects and their relations. This improves interoperability, especially among APIs that provide similar content. Use ontology and vocabulary resources such as BioPortal, Open Biomedical Ontologies and Linked Open Vocabularies to find relevant object types and relations, and consult with FAIRsharing.org and your community for standards and best practices to represent your data resources.

    3. Provide meaningful relations to other resources, particularly between those provided by the API. For instance, if your API provides information about movies and their producers, then the description of a particular movie should provide a qualified reference (e.g. “producer”) to a producer using a shared vocabulary that defines the meaning of the “producer” relation. More linked resources so that agents can share resources and need only to follow provided links, rather that construct their own HTTP calls.

    4. Use formal knowledge representation languages. While JSON is currently the predominant language for web service to receive or return structured data/knowledge, we recommend the use of JSON-LD as a response message. JSON-LD enables JSON messages to be coupled with a context file to associate JSON relations and values with URIs from shared vocabularies. JSON-LD is also a valid RDF syntax, and can be used in more sophisticated platforms for knowledge management and semantic query answering. However, we note that certain types of APIs work directly with binary media types (e.g. images, video, etc), and there is no expectation that the response would be JSON-LD (except when requesting their metadata!).

    5. Offer content negotiation to get different representations of the desired content and maximize immediate reuse. When content is well structured, then it can be readily transformed into a requested format. For instance, content that is prepared for JSON-LD can also be provided as JSON, RDF/XML, Turtle, XHTML, TSV, CSV, and other formats.

    6. Implement only control structures which are contextually relevant and machine readable. Any controls for filtering, sorting, field selection and paging should provide consistent functionality for both human and machine users.

  6. The API MAY implement, where reasonable to do so, modular interfaces for search, browse, retrieve, stream, and other kinds of operations as per existing or emerging community standards. For example, one way to implement a search API is to implement the OpenSearch interface (http://www.opensearch.org), which is supported by many commercial search engines. Developers of new kinds See https://arxiv.org/abs/1609.07108 .

References

  1. The FAIR principles - https://www.nature.com/articles/sdata201618

  2. The smartAPI project - http://smart-api.info.

  3. Hydra, the hypermedia-driven API - http://www.hydra-cg.com/.

  4. The Linked Data Platform - https://www.w3.org/TR/ldp/

  5. Linked Open Vocabularies - http://lov.okfn.org/dataset/lov/

  6. BioPortal - http://bioportal.bioontology.org

  7. Specifying GraphQL metadata - https://github.com/APIs-guru/graphql-apis/blob/master/apis.json

Appendix 1: Notes regarding language specific swagger/openapi generators

Java

Recommended skill-set:

  • Java 8 and upwards

  • Maven

The easiest way to get started is if you already have database services in place. If you are already using Model Classes (e.g. Java Persistence Api) you can easily extend your Java POJO’s (or Beans) with swagger annotations. They will not interfere with JPA annotations. You will need to expose your api is either via JAX-RS web services or via Spring.

Node-JS

Recommended skill-set:

  • Node-JS intermediate

  • NPM package manager

  • And a library to access your toolchain

This is the easiest path to smartAPI. If you follow the official readme it will get you started in no-time. The tools don’t check or change code. You will need to do this manually, but it is straightforward. Most common error is if the mapping is not done right in your code.

Please note that this implementation uses the OpenAPI extension x-swagger-router-controller to define the javascript controller file which will be used for this api-call. The file needs to be stored in the /api/controllers/ directory and should have the same name as defined in the OpenApi extension plus the “js” file extension.

In your controller you can either call functions from service libraries or you can implement the service call. Please keep in mind that everything is done in an async fashion.

Migration from Swagger/OpenApi 3.0 to smartAPI

In Java via annotations

You must switch to Swagger Core v2.X (most current v3) and upwards to generate OpenApi 3.0 definition files. If you are using maven, please keep in mind that the group-id has changed from io.swagger.core to io.swagger.core.v3. See here. Now you will be able to add missing smartAPI extension to your existing code. See here.

Node-JS via swagger-node

You can start with the tool swagger2openapi and convert your Swagger 2.0 project to OpenAPI. After this you will need to add smartAPI extensions manually. This can be done with the integrated Swagger Editor.

Just run to open the editor in a web browser:

$ swagger editor start

see here

Via external tools

You can use a tool called config-merge to merge your OpenApi 3.0 specification file with a predefined specification file containing only those missing Smart-Api extensions