diff --git a/README.md b/README.md index 812fe9d74a..2ddd5aa068 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,50 @@ A versatile and lightweight **API Gateway** for **REST** and **legacy SOAP Web S # Content -- [Getting Started](#Getting-Started) -- [Basics](#Basics) Routing, rewriting -- [Scripting](#scripting) -- [Message Transformation](#message-transformation) -- [Security](#security) -- [Traffic Control](#Traffic-Control) Rate limiting, Load balancing -- [Legacy Web Services](#soap-web-services) SOAP and WSDL -- [Operation](#Operation) +1. [Getting Started](#Getting-Started) + - [Java](#java) + - [Docker](#docker) +2. [Basics](#Basics) Routing, rewriting + - [API Definition and Configuration](#API-Definition-and-Configuration) + - [Simple REST and HTTP Forwarding APIs](#simple-rest-and-http-forwarding-apis) +3. [OpenAPI Support](#openapi-support) + - [Deploy APIs with OpenAPI](#deploy-apis-with-openapi) +4. [Routing](#routing) + - [Short Circuit](#short-circuit) + - [URL Rewriting](#url-rewriting) +5. [Scripting](#scripting) + - [Groovy](#groovy-scripts) + - [Creating Responses with Groovy](#creating-responses-with-groovy) + - [Javascript](#javascript-scripts) +6. [Message Transformation](#message-transformation) + - [Manipulating HTTP Headers](#manipulating-http-headers) + - [Removing HTTP Headers](#removing-http-headers) + - [Create JSON from Query Parameters](#create-json-from-query-parameters) + - [Transform JSON into TEXT, JSON or XML with Templates](#transform-json-into-text-json-or-xml-with-templates) + - [Transform XML into Text or JSON](#transform-xml-into-text-or-json) + - [Complex Transformations using Javascript or Groovy](#complex-transformations-using-javascript-or-groovy) + - [Transformation with Computations](#transformation-with-computations) + - [JSON and XML Beautifier](#json-and-xml-beautifier) +7. [Conditionals with if](#conditionals-with-if) +8. [Security](#security) + - [API Keys](#api-keys) + - [Basic Authentication](#basic-authentication) + - [SSL/TLS](#ssltls) + - [JSON Web Tokens](#json-web-tokens) JWT + - [OAuth2](#oauth2) + - [Secure APIs with OAuth2](#secure-apis-with-oauth2) + - [Membrane as Authorization Server](#membrane-as-authorization-server) + - [XML and JSON Protection](#xml-and-json-protection) +9. [Traffic Control](#Traffic-Control) Rate limiting, Load balancing + - [Rate Limiting](#rate-limiting) + - [Load Balancing](#load-balancing) +8. [Legacy Web Services](#soap-web-services) SOAP and WSDL + - [API configuration from WSDL](#api-configuration-from-wsdl) + - [Message Validation against WSDL and XSD](#message-validation-against-wsdl-and-xsd) +9. [Operation](#Operation) + - [Logging](#log-http) + - [Monitoring with Prometheus and Grafana](#monitoring-with-prometheus-and-grafana) + - [OpenTelemetry](#opentelemetry-integration) # Getting Started @@ -110,17 +146,19 @@ For detailed Docker setup instructions, see the [Membrane Deployment Guide](http - Check out the [SOAP API Tutorial](https://membrane-api.io/tutorials/soap/) for legacy web service integration. ### Read the Documentation + - For detailed guidance, visit the [official documentation](https://www.membrane-soa.org/service-proxy-doc/). # Basics -### Customizing Membrane -To configure Membrane, edit the `proxies.xml` file located in the `conf` folder. +### API Definition and Configuration + +To define new APIs or modify the existing configuration, edit the `proxies.xml` file located in the `conf` folder. This file serves as the central configuration point for managing API behavior and routing rules. ### Using Samples -Explore the sample configurations provided below. Copy and modify them to suit your needs, then save or restart the gateway to apply the changes. +Explore and copy the sample snippets below into the `proxies.xml` file and modify them to suit your needs. Then save or restart the gateway to apply the changes. Usually a save will trigger a reload automatically. -For even more sample have a look at the `examples` folder. +For even more samples have a look at the `examples` folder. ## Simple REST and HTTP Forwarding APIs @@ -139,7 +177,7 @@ To forward requests from the API Gateway to a backend, use a simple `api` config After adding the configuration to the `proxies.xml` file, open the following URL in your browser to test the API: [http://localhost:2000/shop/v2/](http://localhost:2000/shop/v2/) -## Using OpenAPI for Configuration & Validation +## OpenAPI Support ### Deploy APIs with OpenAPI Membrane allows you to configure APIs directly from OpenAPI documents in the `proxies.xml` file. Backend addresses and other details are automatically derived from the OpenAPI description. @@ -346,7 +384,7 @@ You can realize a load balancer by setting the destination randomly. ``` -### Create a Response with Groovy +### Creating Responses with Groovy The `groovy` plugin in Membrane allows you to dynamically generate custom responses. The result of the last line of the Groovy script is passed to the plugin. If the result is a `Response` object, it will be returned to the caller. @@ -395,7 +433,7 @@ For more information about using Groovy with Membrane, refer to: - [Groovy Plugin Reference](https://www.membrane-api.io/docs/current/groovy.html). - [Sample Project](distribution/examples/groovy) -### JavaScript Extension +### JavaScript Scripts In addition to Groovy, Membrane supports JavaScript for implementing custom behavior. This allows you to inspect, modify, or log details about requests and responses. @@ -420,6 +458,23 @@ The following example logs all HTTP headers from incoming requests and responses The `CONTINUE` keyword ensures that the request continues processing and is forwarded to the target URL. +When a JavaScript script returns a `Response` object as the last line of code, the request flow is interrupted, and the response is sent back to the client. This allows for creating custom responses dynamically. + +The following example generates a JSON response and sends it directly to the client: + +```xml + + + var body = JSON.stringify({ + foo: 7, + bar: 42 + }); + + Response.ok(body).contentType("application/json").build(); + + +``` + #### Learn More For more details about using JavaScript with Membrane, check the [JavaScript Plugin documentation](https://www.membrane-api.io/docs/current/javascript.html). @@ -643,7 +698,7 @@ This script transforms the input and adds some calculations. See [examples/javascript](distribution/examples/javascript) for a detailed explanation. The same transformation can also be realized with [Groovy](distribution/examples/groovy) -## Beautifier +## JSON and XML Beautifier You can beautify a JSON or XML using the `` plugin. @@ -669,11 +724,11 @@ Returns: ``` -# Branching and Conditionals +# Conditionals with if Replace `5XX` error messages from a backend: -```xml +```xml @@ -686,17 +741,6 @@ Replace `5XX` error messages from a backend: ``` -Check if certain scopes/roles are provided: -```xml - - - - - - - -``` - # Writing Extensions with Groovy or Javascript Dynamically manipulate and monitor messages with Groovy: @@ -876,6 +920,49 @@ Secure endpoints with SSL/TLS: ``` +### XML and JSON Protection + +Membrane offers protection mechanisms to secure your APIs from common risks associated with XML and JSON payloads. + +#### XML Protection + +The `xmlProtection` plugin inspects incoming XML requests and mitigates risks such as: + +- External entity references (XXE attacks). +- Excessively large element names. +- High numbers of attributes or deeply nested structures. + +**Example:** +```xml + + + + +``` + +See [XML Protection Reference](https://www.membrane-api.io/docs/current/xmlProtection.html). + +#### JSON Protection + +The `jsonProtection` plugin safeguards APIs from JSON-based vulnerabilities by setting limits on: + +- **Depth**: Prevents overly nested JSON structures. +- **Key Length**: Restricts excessively long keys. +- **Object Size**: Maximum number of fields in aJSON object. +- **String Length**: Controls maximum length of string values. +- **...** + +**Example:** + +```xml + + + + +``` + +See [JSON Protection](https://www.membrane-api.io/docs/current/jsonProtection.html). + # Traffic Control ## Rate Limiting @@ -909,20 +996,6 @@ Distribute workload to multiple backend nodes. [See the example](distribution/ex ``` -# Log HTTP - -Log data about requests and responses to a file or [database](distribution/examples/logging/jdbc-database) as [CSV](distribution/examples/logging/csv) -or [JSON](distribution/examples/logging/json) file. - -```xml - - - - - - -``` - # Websockets Route and intercept WebSocket traffic: @@ -966,8 +1039,56 @@ The _validator_ checks SOAP messages against a WSDL document including reference # Operation +## Log HTTP + +Log data about requests and responses to a file or [database](distribution/examples/logging/jdbc-database) as [CSV](distribution/examples/logging/csv) +or [JSON](distribution/examples/logging/json) file. + +```xml + + + + + + +``` + ## Instrumentation +### Monitoring with Prometheus and Grafana + +Membrane supports seamless monitoring with Prometheus and Grafana, enabling visibility into API performance and system metrics. + +Add an API with the `prometheus` plugin to your `proxies.xml` file. This will expose metrics at the specified endpoint: + +```xml + + /metrics + + +``` + +Then you can query the metrics by navigating to: +[http://localhost:2000/metrics](http://localhost:2000/metrics). + +This endpoint provides Prometheus-compatible metrics, which you can scrape using a Prometheus server. + +For a complete configuration example with Prometheus and Grafana, refer to: +[Prometheus Example](distribution/examples/prometheus). + +### Monitoring with Prometheus and Grafana + +Add an API with the `prometheus` plugin at the top of the `proxies.xml` file. + +```xml + + /metrics + + +``` + +Then query the metrics endpoint by opening [http://localhost:2000/metrics](http://localhost:2000/metrics). Now you can setup a prometheus to scrape that endpoint. For a complete example with prometheus and Grafana have a look at [examples/prometheus](distribution/examples/prometheus). + ### OpenTelemetry Integration Membrane supports integration with **OpenTelemetry** traces using the `openTelemetry` plugin and the `W3C` propagation standard. This enables detailed tracing of requests across Membrane and backend services. diff --git a/distribution/examples/prometheus/README.md b/distribution/examples/prometheus/README.md index 406497c855..0631158eec 100644 --- a/distribution/examples/prometheus/README.md +++ b/distribution/examples/prometheus/README.md @@ -5,10 +5,13 @@ Membrane supports monitoring through the integration with Prometheus. With the Prometheus plugin, Membrane enables the observation of APIs. It gathers metrics about the processes passing through it and makes them available for scraping by Prometheus. This data can then be used for monitoring and alerting purposes. To enable monitoring for an API, simply add the Prometheus plugin to it. + ## Run the Example To monitor APIs using Prometheus and Grafana, follow the steps below: +### Providing a Metrics Endpoint for Prometheus + 1. Start the example environment with Docker Compose: ```bash @@ -17,11 +20,11 @@ To monitor APIs using Prometheus and Grafana, follow the steps below: 2. Access the following endpoints: - - [localhost:2001](http://localhost:2001) - Returns a status code of 200. - - [localhost:2002](http://localhost:2002) - Returns a status code of 404. - - [localhost:2003](http://localhost:2003) - Returns a status code of 500. +- [localhost:2001](http://localhost:2001) - Returns a status code of 200. +- [localhost:2002](http://localhost:2002) - Returns a status code of 404. +- [localhost:2003](http://localhost:2003) - Returns a status code of 500. - You can use cURL commands to access these endpoints, e.g.: +You can use cURL commands to access these endpoints, e.g.: ```bash curl -v http://localhost:2001 @@ -29,14 +32,25 @@ To monitor APIs using Prometheus and Grafana, follow the steps below: curl -v http://localhost:2003 ``` -3. After accessing the endpoints, proceed to Grafana: +3. Then, query the metrics endpoint of Membrane + + - Open [http://localhost:2000/metrics](http://localhost:2000/metrics) + +### Quering Prometheus + +1. Open Prometheus at [http://localhost:9090](http://localhost:9090) +2. Search for `membrane_count` + +### Grafana + +1. Proceed to Grafana: - - Access [localhost:3000](http://localhost:3000) in your browser. - - Log in with the default credentials: username `admin` and password `admin`. - - Click on "Explore" from the left-hand menu. - - You can now select different queries to display the collected metrics. +- Access [localhost:3000](http://localhost:3000) in your browser. +- Log in with the default credentials: username `admin` and password `admin`. +- Click on "Explore" from the left-hand menu. +- You can now select different queries to display the collected metrics. - ![Grafana example](prometheus-grafana-example.png) +![Grafana example](prometheus-grafana-example.png) **HOW IT IS DONE** @@ -45,6 +59,7 @@ Take a look at the `proxies.xml`. ```xml + /metrics diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000000..7b26d2c0a0 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,7 @@ +# Membrane Roadmap + +# Version 6.0.0 + +- Grafana Dashboard to import in examples/prometheus + - Also provide the datasource config + - Maybe the config can be included into the docker-compose setup