0.1.4 • Published 2 years ago

@api-components/amf-web-api v0.1.4

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
2 years ago

AMF Web API

A node web server that runs on Koa that provides an API to parse an API using the AMF parser.

Usage

Installation

npm i @api-components/amf-web-api

Running the server

import Server from '@api-components/amf-web-api';

(async () => {
  const httpPort = 8080;
  const sslPort = 8081;

  const sslOptions = {
    key: fs.readFileSync('key.pem'),
    cert: fs.readFileSync('cert.pem')
  };
  
  const srv = new Server();
  srv.setupRoutes('/api/v1'); // optional prefix for the API routes.

  await srv.startHttp(httpPort);
  await srv.startSsl(sslOptions, httpPort);

  // when ready...
  await srv.stopHttp(); 
  await srv.stopSsl(); 
})();

API routes

See the API spec in spec/ folder for more details.

Notes:

  • Examples assume no API prefix and port 8080
  • Example responses are formatted for readability

Parsing a text content

This endpoint creates a task to parse the content. It does not wait for the parsing result. Instead it returns the location of the endpoint to query for the parsing result.

The x-api-vendor is required and it is the API vendor to use. It is one of the API vendors supported by the AMF parser: RAML 0.8, RAML 1.0, OAS 2.0, OAS 3.0, and ASYNC 2.0.

The content type is optional and is ignored by the server. However, it is a good practice to keep it and set the correct value.

Plain text request

POST /text HTTP/1.1
Host: localhost:8080
Content-Type: application/raml
x-api-vendor: RAML 1.0
content-length: 147

#%RAML 1.0
title: Demo API

version: v2
baseUri: https://api.mulesoft.com/{version}
mediaType: application/json
protocols: [HTTPS]

Plain text response

HTTP/1.1 201 Created
location: /job/64d7ed3c-d598-479c-920b-9d19ed002917
Content-Type: application/json; charset=utf-8
Content-Length: 121
Date: Sat, 06 Nov 2021 00:01:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{
  "status": 201,
  "location": "/job/64d7ed3c-d598-479c-920b-9d19ed002917",
  "key":"64d7ed3c-d598-479c-920b-9d19ed002917"
}

Parsing an API project in a zip file

To parse an entire API project with multiple files send a zip file in the request body.

You can set an optional x-entrypoint header with the name of the API's main file (the entry point). When the header is not set then the server application tries to determine the best candidate using some built-in heuristics.

When multiple entrypoints are found in the project then the job status endpoint returns the list of files with the 300 status code. The client should pick one (probably involving the user). After the pick is ready the client sends the PUT request to the job status endpoint (see below).

When a single endpoint is found in the API project then it is used automatically as the entrypoint. When no files are found then the process ends with an error.

File request

POST /file HTTP/1.1
Host: localhost:8080
Content-Type: application/zip
content-length: 3576

[binary content]

File response

HTTP/1.1 201 Created
location: /job/c04401ec-eccd-45e7-b004-0d2884be6d5c
Content-Type: application/json; charset=utf-8
Content-Length: 121
Date: Sat, 06 Nov 2021 00:01:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{
  "status": 201,
  "location": "/job/c04401ec-eccd-45e7-b004-0d2884be6d5c",
  "key":"c04401ec-eccd-45e7-b004-0d2884be6d5c"
}

Reading the job status

The request:

GET /job/c04401ec-eccd-45e7-b004-0d2884be6d5c HTTP/1.1
Host: localhost:8080

Parsing result is ready

When the parsing result is ready the response returns the ld+json model generated by the AMF library. After that the process is removed from the server and it is impossible to read the value again.

The response:

HTTP/1.1 200 OK
Content-Type: application/ld+json
Content-Length: 86868
Date: Sat, 06 Nov 2021 00:04:47 GMT

{
  "@graph": [
    {
      "@id": "#37",
      "@type": [
        "doc:APIContractProcessingData"
      ],
      "apiContract:modelVersion": "3.2.0",
      "doc:transformed": true,
      "doc:sourceSpec": "OAS 2.0"
    },
    {
      "@id": "#38",
      "@type": [
        "apiContract:WebAPI",
        "apiContract:API",
        "doc:RootDomainElement",
        "doc:DomainElement"
      ],
      "core:name": "Swagger Petstore",
      "core:description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
      "apiContract:server": [
....

Parsing result is not ready

This response is returned when the parser is still running. This may happen in case of a very complex API. In this case the client should wait and try again. Note, too many requests may cause the server to refuse serving the content. It will return the 429 and 425 status codes respectively. See the RAML spec for the details.

HTTP/1.1 204 OK
location: /job/c04401ec-eccd-45e7-b004-0d2884be6d5c
Date: Sat, 06 Nov 2021 00:04:47 GMT

Cannot determine an entry point

This happens when parsing a zip file. When the application cannot determine the entry point to the API spec file and the x-entrypoint header was not set on the request then the response contains the list of potential candidates that the client (and possibly the user) should choose from.

HTTP/1.1 300 Multiple Choices
Content-Type: application/json
Content-Length: 125
Date: Sat, 06 Nov 2021 00:04:47 GMT

{
  "files": [
    "my-api.raml",
    "other.json"
  ]
}

The files returned this way have an API header (RAML, swagger, OAS, Async) and all can be used as an entry point. When the client choose the entrypoint then it should send the PUT request to the same endpoint. See below for details.

Informing about the entrypoint

The easiest way is to set the x-entrypoint header on the /files request. However, it is not always possible or desired. In this case the status endpoint returns the list of entrypoints it thinks is to be the best matches for an endpoint. Once picked, send the entrypoint name in the PUT request to the job status.

PUT /job/c04401ec-eccd-45e7-b004-0d2884be6d5c HTTP/1.1
Host: localhost:8080
Content-Type: application/json
content-length: 28

{
  "entrypoint": "my-api.raml"
}

This will result with the same response as with the /file endpoint.

Deleting a job

When the client is sure that the result won't be read it should send the DELETE request to the job status endpoint to delete processing of the API and cleanup the resources.

Note, the parser process has a timeout after which it is automatically cleaned from memory when not used.

Development

git clone https://github.com/api-components/amf-web-api
cd amf-web-api
npm install

Running the tests

npm test

Note, Firefox is temporarily removed from tests until Playwright update FF version to at least 91.

Credits and license

This library has been created by Pawel Uchida-Psztyc on his own free time. It is licensed under Apache 2 license.