LIGHT

  • News
  • Docs
  • Community
  • Reddit
  • GitHub

OpenAPI Backend

This tutorial will create a backend service and start three instances to demo the light-proxy load balance between them.

The backend service will have two endpoints: one get and one post to demo different proxy functionality scenarios. This server is built on top of light-rest-4j with OpenAPI 3.0 specification.

Backend service specification and light-codegen config.json

You can find the OpenAPI 3.0 specification and config.json in model-config

Regarding how to create OpenAPI 3.0 Specification, please refer to swagger editor

Generate the backend service

Given the OpenAPI specification and config.json, we will use light-codegen to generate the project and update the service with a meaningful response based on the specification.

cd ~/networknt
git clone https://github.com/networknt/light-example-4j.git
git clone https://github.com/networknt/light-codegen.git
git clone https://github.com/networknt/model-config.git
git clone https://github.com/networknt/light-config-test.git
cd light-codegen
mvn clean install -DskipTests
cd ~/networknt
rm -rf light-example-4j/rest/openapi/proxy-backend
java -jar light-codegen/codegen-cli/target/codegen-cli.jar -f openapi -o light-example-4j/rest/openapi/proxy-backend -m model-config/rest/openapi/proxy-backend/openapi.yaml -c model-config/rest/openapi/proxy-backend/config.json

The newly generated project can be found in light-example-4j, and you can compare it with your own generated code.

Update handlers

Now with the project generated, let’s update the two handlers to output some meaningful info when the endpoints are called.

Here is the GetDataGetHandler.java

package com.networknt.backend.handler;

import com.networknt.config.Config;
import com.networknt.server.Server;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.HttpString;

import java.util.HashMap;
import java.util.Map;

public class GetDataGetHandler implements HttpHandler {
    static final boolean enableHttp2 = Server.getServerConfig().isEnableHttp2();
    static final boolean enableHttps = Server.getServerConfig().isEnableHttps();
    static final int httpPort = Server.getServerConfig().getHttpPort();
    static final int httpsPort = Server.getServerConfig().getHttpsPort();

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        Map<String, Object> examples = new HashMap<>();
        examples.put("key", "key1");
        examples.put("value", "value1");
        examples.put("enableHttp2", enableHttp2);
        examples.put("enableHttps", enableHttps);
        examples.put("httpPort", httpPort);
        examples.put("httpsPort", httpsPort);
        exchange.getResponseHeaders().add(new HttpString("Content-Type"), "application/json");
        exchange.getResponseSender().send(Config.getInstance().getMapper().writeValueAsString(examples));
    }
}

Here is the PostDataPostHandler.java


package com.networknt.backend.handler;

import com.networknt.body.BodyHandler;
import com.networknt.config.Config;
import com.networknt.server.Server;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.HttpString;
import org.apache.commons.lang3.StringEscapeUtils;

import java.util.HashMap;
import java.util.Map;

public class PostDataPostHandler implements HttpHandler {
    static final boolean enableHttp2 = Server.getServerConfig().isEnableHttp2();
    static final boolean enableHttps = Server.getServerConfig().isEnableHttps();
    static final int httpPort = Server.getServerConfig().getHttpPort();
    static final int httpsPort = Server.getServerConfig().getHttpsPort();

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        Map<String, Object> body = (Map<String, Object>)exchange.getAttachment(BodyHandler.REQUEST_BODY);
        Map<String, Object> examples = new HashMap<>(body);
        examples.put("enableHttp2", enableHttp2);
        examples.put("enableHttps", enableHttps);
        examples.put("httpPort", httpPort);
        examples.put("httpsPort", httpsPort);
        exchange.getResponseHeaders().add(new HttpString("Content-Type"), "application/json");
        exchange.getResponseSender().send(Config.getInstance().getMapper().writeValueAsString(examples));
    }
}

As you can see, the output contains information on which port the response is coming from, as we will start multiple instances of the backend for the proxy.

Start backend services

If you have multiple computers, you can start multiple instances listening on the same port on each computer. Otherwise, start multiple instances that listening to different ports on one computer. Here we will start three instances on the same computer and let them listen to 8081, 8082 and 8083 on HTTPS. Let’s disable the HTTP for now, as it is never used on production.

If you generate the proxy-backend service, you should already have the project on your local light-example-4j/rest/openapi folder. If not, let’s clone the repo and compile it locally.

cd ~/networknt
git clone https://github.com/networknt/light-example-4j.git

To start three instances with different HTTPS ports, we need to overwrite the httpsPort in server.yml, which is located at proxy-backend/src/main/resources/config folder with an external values.yml file. The following is the default one generated based on the config.json file. As you can see, HTTP is disabled, and HTTPS is enabled and listen to port 8443.



# Server configuration
---
# This is the default binding address if the service is dockerized.
ip: 0.0.0.0

# Http port if enableHttp is true.
httpPort:  8080

# Enable HTTP should be false on official environment.
enableHttp: false

# Https port if enableHttps is true.
httpsPort:  8443

# Enable HTTPS should be true on official environment.
enableHttps: true

# Http/2 is enabled by default.
enableHttp2: true

# Keystore file name in config folder. KeystorePass is in secret.yml to access it.
keystoreName: tls/server.keystore

# Flag that indicate if two way TLS is enabled. Not recommended in docker container.
enableTwoWayTls: false

# Truststore file name in config folder. TruststorePass is in secret.yml to access it.
truststoreName: tls/server.truststore

# Unique service identifier. Used in service registration and discovery etc.
serviceId: com.networknt.backend-1.0.0

# Flag to enable service registration. Only be true if running as standalone Java jar.
enableRegistry: false

# environment tag that will be registered on consul to support multiple instances per env for testing.
# https://github.com/networknt/light-doc/blob/master/docs/content/design/env-segregation.md
# This tag should only be set for testing env, not production. The production certification process will enforce it.
# environment: test1

The externalized values.yml files for httpsPort 8081, 8082 and 8083 can be found at https://github.com/networknt/light-config-test/tree/master/light-example-4j/rest/openapi/proxy-backend and the repository has been checked out locally.

Now let’s start the first instance in a new terminal.

cd ~/networknt/light-example-4j/rest/openapi/proxy-backend
mvn clean install -Prelease
java -Dlight-4j-config-dir=/home/steve/networknt/light-config-test/light-example-4j/rest/openapi/proxy-backend/8081 -jar target/backend-1.0.0.jar

Please note that the configuration folder might be different on your computer.

You can issue a curl command from another terminal to ensure the server runs and listens on 8081 on HTTPS/HTTP2.

curl -k https://localhost:8081/v1/getData

Result:

{"enableHttp2":true,"httpPort":8080,"enableHttps":true,"value":"value1","httpsPort":8081,"key":"key1"}

You can also test the post request with the following command line.

curl -k -X POST https://localhost:8081/v1/postData   -H 'content-type: application/json'   -d '{"key":"key1", "value": "value1"}'

And the response should be something like this.

{"enableHttps":true,"value":"value1","httpsPort":8081,"key":"key1","enableHttp2":true,"httpPort":8080}

Let’s start another service in another terminal with the 8082 config folder to overwrite the HTTPS port to 8082.

cd ~/networknt/light-example-4j/rest/openapi/proxy-backend
java -Dlight-4j-config-dir=/home/steve/networknt/light-config-test/light-example-4j/rest/openapi/proxy-backend/8082 -jar target/backend-1.0.0.jar

Please note that the configuration folder might be different on your computer.

Test the second instance with the command:

curl -k https://localhost:8082/v1/getData

Now let’s start the third instance with port number 8083.

cd ~/networknt/light-example-4j/rest/openapi/proxy-backend
java -Dlight-4j-config-dir=/home/steve/networknt/light-config-test/light-example-4j/rest/openapi/proxy-backend/8083 -jar target/backend-1.0.0.jar

Please note that the configuration folder might be different on your computer.

Test the third instance with the command:

curl -k https://localhost:8083/v1/getData

At this moment, we have three backend service instances running, and they are listening to 8081, 8082, and 8083 on the HTTPS/HTTP2 protocol.

A video walkthrough in English can be found here

A video walkthrough in Chinese can be found here

  • 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 Backend” was last updated: June 27, 2021: fixes #271 update TestServer to replace Server.config with Server.getServerConfig method (b34d9c7)
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