Skip to content

OpenAPI Path Templating parser, validator and resolver.

License

Notifications You must be signed in to change notification settings

swaggerexpert/openapi-path-templating

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

openapi-path-templating

npmversion npm Test workflow Dependabot enabled try on RunKit Tidelift

OpenAPI Path Templating refers to the usage of template expressions, delimited by curly braces ({}), to mark a section of a URL path as replaceable using path parameters. Each template expression in the path MUST correspond to a path parameter that is included in the Path Item itself and/or in each of the Path Item's Operations. An exception is if the path item is empty, for example due to ACL constraints, matching path parameters are not required.

openapi-path-templating is a parser, validator, and resolver for OpenAPI Path Templating, which played a foundational role in defining the official ANBF grammar for OpenAPI Path Templating.

It supports Path Templating defined in following OpenAPI specification versions:

Tidelift Get professionally supported openapi-path-templating with Tidelift Subscription.

Table of Contents

Getting started

Installation

You can install openapi-path-templating using npm:

 $ npm install openapi-path-templating

Usage

openapi-path-templating currently supports parsing, validation and resolution. Both parser and validator are based on a superset of ABNF (SABNF) and use apg-lite parser generator.

Parsing

Parsing a Path Templating is as simple as importing the parse function and calling it.

import { parse } from 'openapi-path-templating';

const parseResult = parse('/pets/{petId}');
parseResult.result.success; // => true

parseResult variable has the following shape:

{
  result: {
    success: true,
    state: 101,
    stateName: 'MATCH',
    length: 13,
    matched: 13,
    maxMatched: 13,
    maxTreeDepth: 20,
    nodeHits: 232
  },
  ast: fnast {
    callbacks: [
      'path-template': [Function: pathTemplate],
      slash: [Function: slash],
      'path-literal': [Function: pathLiteral],
      'template-expression': [Function: templateExpression],
      'template-expression-param-name': [Function: templateExpressionParamName]
    ],
    init: [Function (anonymous)],
    ruleDefined: [Function (anonymous)],
    udtDefined: [Function (anonymous)],
    down: [Function (anonymous)],
    up: [Function (anonymous)],
    translate: [Function (anonymous)],
    setLength: [Function (anonymous)],
    getLength: [Function (anonymous)],
    toXml: [Function (anonymous)]
  }
}
Interpreting AST as list of entries
import { parse } from 'openapi-path-templating';

const parseResult = parse('/pets/{petId}');
const parts = [];

parseResult.ast.translate(parts);

After running the above code, parts variable has the following shape:

[
  [ 'path-template', '/pets/{petId}' ],
  [ 'slash', '/' ],
  [ 'path-literal', 'pets' ],
  [ 'slash', '/' ],
  [ 'template-expression', '{petId}' ],
  [ 'template-expression-param-name', 'petId' ]
]
Interpreting AST as XML
import { parse } from 'openapi-path-templating';

const parseResult = parse('/pets/{petId}');
const xml = parseResult.ast.toXml();

After running the above code, xml variable has the following content:

<?xml version="1.0" encoding="utf-8"?>
<root nodes="6" characters="13">
  <!-- input string -->
  /pets/{petId}
  <node name="path-template" index="0" length="13">
    /pets/{petId}
    <node name="slash" index="0" length="1">
      /
    </node><!-- name="slash" -->
    <node name="path-literal" index="1" length="4">
      pets
    </node><!-- name="path-literal" -->
    <node name="slash" index="5" length="1">
      /
    </node><!-- name="slash" -->
    <node name="template-expression" index="6" length="7">
      {petId}
      <node name="template-expression-param-name" index="7" length="5">
        petId
      </node><!-- name="template-expression-param-name" -->
    </node><!-- name="template-expression" -->
  </node><!-- name="path-template" -->
</root>

NOTE: AST can also be traversed in classical way using depth first traversal. For more information about this option please refer to apg-js and apg-js-examples.

Validation

Validating a Path Templating is as simple as importing the test function and calling it.

import { test } from 'openapi-path-templating';

test('/pets/{petId}'); // => true
test('/a{petId}'); // => true
test('/pets'); // => true
test('/pets', { strict: true }); // => false (doesn't contain any template-expression)

Resolution

Resolving a Path Templating is as simple as importing the resolve function and calling it.

import { resolve } from 'openapi-path-templating';

resolve('/pets/{petId}', { petId: 3 }); // => "/pets/3"

Resolved Path Templating is automatically encoded using encodeURIComponent function. It is possible to provide a custom encoder.

import { resolve } from 'openapi-path-templating';

resolve('/pets/{petId}', { petId: '/?#' }, {
  encoder: (component) => component, // no encoding
}); // => "/pets//?#"

Grammar

New grammar instance can be created in following way:

import { Grammar } from 'openapi-path-templating';

const grammar = new Grammar();

To obtain original ABNF (SABNF) grammar as a string:

import { Grammar } from 'openapi-path-templating';

const grammar = new Grammar();

grammar.toString();
// or
String(grammar);

More about OpenAPI Path Templating

The Path Templating is defined by the following ABNF syntax

; OpenAPI Path Templating ABNF syntax
path-template                  = slash *( path-segment slash ) [ path-segment ]
path-segment                   = 1*( path-literal / template-expression )
slash                          = "/"
path-literal                   = 1*pchar
template-expression            = "{" template-expression-param-name "}"
template-expression-param-name = 1*( %x00-7A / %x7C / %x7E-10FFFF ) ; every UTF8 character except { and } (from OpenAPI)

; Characters definitions (from RFC 3986)
pchar               = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved          = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded         = "%" HEXDIG HEXDIG
sub-delims          = "!" / "$" / "&" / "'" / "(" / ")"
                    / "*" / "+" / "," / ";" / "="

; Characters definitions (from RFC 5234)
ALPHA               = %x41-5A / %x61-7A   ; A-Z / a-z
DIGIT               = %x30-39            ; 0-9
HEXDIG              = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"

License

openapi-path-templating is licensed under Apache 2.0 license. openapi-path-templating comes with an explicit NOTICE file containing additional legal notices and information.