LIGHT

  • News
  • Docs
  • Community
  • Reddit
  • GitHub

OpenAPI Parser

The OpenApi Parser is based on the generated code of KaiZen OpenApi Parser from RepreZen which is a Java-based validating parser for OpenAPI 3.0 offering full compliance with the OpenAPI 3.0 Specification, and a highly uniform read/write programming API. OpenAPI, formerly known as the Swagger specification is the industry-standard format for machine-readable REST API descriptions.

By removing the generator from KaiZen parser, this library doesn’t depend on any external dependencies, which make it a green library suitable for microservices.

Feature highlights of OpenAPI Parser include:

  • High Performance - Informal testing shows a 3x-4x performance improvement over the current Java Swagger 2.0 parser. This is largely attributable to a design based on adapting Jackson JsonNode objects, rather than deserializing to internal POJOs.

  • Read/Write API - All aspects of a model may be interrogated and modified. We also provide fluent builders for all model object types. We provide bidirectional navigation throughout the model, and every object that is a property value of its containing object (whether as a named field or a map entry) knows its own key.

  • Tolerant Reader - The parser yields a fully accessible result from any valid JSON or YAML input - whether or not the input is a valid OpenAPI specification.

  • Separate, extensible validation - All validation beyond base JSON/YAML parsing is performed after the initial parse, and it can be disabled for speed. Model-level validation (i.e. anything that can be checked with our provided Java API) is separated from injectable implementation-level validation. The latter covers anything that needs to look “under the covers”, using methods of the implementation classes that lie outside the model API. For example, this is where unrecognized JSON properties would be noted and flagged, as they are not visible from the model API.

  • Serialization - Serialization to JSON or YAML is supported, and by default, round-tripping will not cause any reordering of model content.

  • DI-Ready - Our API is interface-based and allows substitution of custom implementations that either augment or completely replace our provided implementation, using Singleton Service Factory dependency injection.

  • Green - This library doesn’t depend on any external dependencies which makes it light-weight and suitable for microservices.

  • Flexible Reference Handling - References are detected and resolved after JSON/YAML parsing but before model-level parsing. All JSON references are processed, resulting in effective inlining for non-conforming references (i.e. anything other than path or component references specifically allowed in the specification). References are normally traversed automatically by the API, but full details of references and their resolution status are also available.

Getting Started

You can try the parser with the following simple program, or of course, explore with your own models.

The program parses each of the examples OpenAPI 3.0 models currently available in the OAI/OpenAPI-Specification GitHub Repo. In each case, if validation succeeds, a summary of all the model’s paths, operations, and operation parameters is printed. Otherwise, all validation messages are printed.

At the time of this writing, validation fails on the callback-example because that example does not include the required openapi and info properties.

package com.networknt.oas;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.oas.model.OpenApi3;
import com.networknt.oas.validator.ValidationResults.ValidationItem;
import com.networknt.utility.NioUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

@RunWith(Parameterized.class)
public class ExamplesTest extends Assert {

	private static final String SPEC_REPO = "OAI/OpenAPI-specification";
	private static final String EXAMPLES_BRANCH = "master";
	private static final String EXAMPLES_ROOT = "examples/v3.0";

	private static ObjectMapper mapper = new ObjectMapper();

	@Parameters(name = "{index}: {1}")
	public static Collection<Object[]> findExamples() throws IOException {
		Collection<Object[]> examples = new ArrayList<>();
		Deque<URL> dirs = new ArrayDeque<>();
		String auth = System.getenv("GITHUB_AUTH") != null ? System.getenv("GITHUB_AUTH") + "@" : "";
		String request = String.format("https://%sapi.github.com/repos/%s/contents/%s?ref=%s", auth, SPEC_REPO,
				EXAMPLES_ROOT, EXAMPLES_BRANCH);
		dirs.add(new URL(request));
		while (!dirs.isEmpty()) {
			URL url = dirs.remove();
			try (InputStream is = url.openStream()) {
				String json = NioUtils.toString(is);
				JsonNode tree = mapper.readTree(json);
				for (JsonNode result : iterable(tree.elements())) {
					String type = result.get("type").asText();
					String path = result.get("path").asText();
					String resultUrl = result.get("url").asText();
					if (type.equals("dir")) {
						dirs.add(new URL(resultUrl));
					} else if (type.equals("file") && (path.endsWith(".yaml") || path.endsWith(".json"))) {
						String downloadUrl = result.get("download_url").asText();
						examples.add(new Object[] { new URL(downloadUrl), result.get("name").asText() });
					}
				}
			}
		}
		return examples;
	}

	@Parameter
	public URL exampleUrl;

	@Parameter(1)
	public String fileName;

	@Test
	public void exampleCanBeParsed() throws IOException {
		if (!exampleUrl.toString().contains("callback-example")) {
			OpenApi3 model = (OpenApi3) new OpenApiParser().parse(exampleUrl);
			for (ValidationItem item : model.getValidationItems()) {
				System.out.println(item);
			}
			assertTrue("Example was not valid: " + exampleUrl, model.isValid());
		}
	}

	private static <T> Iterable<T> iterable(final Iterator<T> iterator) {
		return new Iterable<T>() {
			@Override
			public Iterator<T> iterator() {
				return iterator;
			}
		};
	}
}

API Overview

To be completed.

Resources

  • Blog Post: Introducing KaiZen OpenAPI 3.0 Parser: fast, flexible Java parsing & validation
  • KaiZen OpenAPI 3.0 Parser
  • About Light
    • Overview
    • Testimonials
    • What is Light
    • Features
    • Principles
    • Benefits
    • Roadmap
    • Community
    • Articles
    • Videos
    • License
    • Why Light Platform
  • Getting Started
    • Get Started Overview
    • Environment
    • Light Codegen Tool
    • Light Rest 4j
    • Light Tram 4j
    • Light Graphql 4j
    • Light Hybrid 4j
    • Light Eventuate 4j
    • Light Oauth2
    • Light Portal Service
    • Light Proxy Server
    • Light Router Server
    • Light Config Server
    • Light Saga 4j
    • Light Session 4j
    • Webserver
    • Websocket
    • Spring Boot Servlet
  • Architecture
    • Architecture Overview
    • API Category
    • API Gateway
    • Architecture Patterns
    • CQRS
    • Eco System
    • Event Sourcing
    • Fail Fast vs Fail Slow
    • Integration Patterns
    • JavaEE declining
    • Key Distribution
    • Microservices Architecture
    • Microservices Monitoring
    • Microservices Security
    • Microservices Traceability
    • Modular Monolith
    • Platform Ecosystem
    • Plugin Architecture
    • Scalability and Performance
    • Serverless
    • Service Collaboration
    • Service Mesh
    • SOA
    • Spring is bloated
    • Stages of API Adoption
    • Transaction Management
    • Microservices Cross-cutting Concerns Options
    • Service Mesh Plus
    • Service Discovery
  • Design
    • Design Overview
    • Design First vs Code First
    • Desgin Pattern
    • Service Evolution
    • Consumer Contract and Consumer Driven Contract
    • Handling Partial Failure
    • Idempotency
    • Server Life Cycle
    • Environment Segregation
    • Database
    • Decomposition Patterns
    • Http2
    • Test Driven
    • Multi-Tenancy
    • Why check token expiration
    • WebServices to Microservices
  • Cross-Cutting Concerns
    • Concerns Overview
  • API Styles
    • Light-4j for absolute performance
    • Style Overview
    • Distributed session on IMDG
    • Hybrid Serverless Modularized Monolithic
    • Kafka - Event Sourcing and CQRS
    • REST - Representational state transfer
    • Web Server with Light
    • Websocket with Light
    • Spring Boot Integration
    • Single Page Application
    • GraphQL - A query language for your API
    • Light IBM MQ
    • Light AWS Lambda
    • Chaos Monkey
  • Infrastructure Services
    • Service Overview
    • Light Proxy
    • Light Mesh
    • Light Router
    • Light Portal
    • Messaging Infrastructure
    • Centralized Logging
    • COVID-19
    • Light OAuth2
    • Metrics and Alerts
    • Config Server
    • Tokenization
    • Light Controller
  • Tool Chain
    • Tool Chain Overview
  • Utility Library
  • Service Consumer
    • Service Consumer
  • Development
    • Development Overview
  • Deployment
    • Deployment Overview
    • Frontend Backend
    • Linux Service
    • Windows Service
    • Install Eventuate on Windows
    • Secure API
    • Client vs light-router
    • Memory Limit
    • Deploy to Kubernetes
  • Benchmark
    • Benchmark Overview
  • Tutorial
    • Tutorial Overview
  • Troubleshooting
    • Troubleshoot
  • FAQ
    • FAQ Overview
  • Milestones
  • Contribute
    • Contribute to Light
    • Development
    • Documentation
    • Example
    • Tutorial
“OpenAPI Parser” was last updated: July 5, 2021: fixes #275 checked and corrected grammar/spelling for majority of pages (#276) (b3bbb7b)
Improve this page
  • News
  • Docs
  • Community
  • Reddit
  • GitHub
  • About Light
  • Getting Started
  • Architecture
  • Design
  • Cross-Cutting Concerns
  • API Styles
  • Infrastructure Services
  • Tool Chain
  • Utility Library
  • Service Consumer
  • Development
  • Deployment
  • Benchmark
  • Tutorial
  • Troubleshooting
  • FAQ
  • Milestones
  • Contribute