Lura Framework Documentation

repository·master·Indexed 27 days ago

https://github.com/luraproject/lura

Lura is an open Go library and framework for assembling high-performance API Gateways, proxies, or RPC gateways. It acts as an aggregator and proxy between clients and backend services, simplifying client-side complexity through response transformation, endpoint aggregation, and a stackable middleware system. The framework consists of three primary layers: the config package for service definition, the router package for managing HTTP(S) endpoints, and the proxy package for request/response processing.

Tokens
4.4K
Snippets
5
Records
26
Agent score
92%

What's inside Lura

  1. Get started with the Lura Project

    master
    Lura is a framework designed for building high-performance systems. To understand the individual components and how they interact, refer to the framework overview documentation. For a real-world implementation example, examine the KrakenD CE API Gateway project, which utilizes the Lura framework.
  2. Understand the Lura framework architecture

    master

    Lura is a framework designed to create pipes and processors between exposed endpoints and backend API resources. It is built using three primary layers:

    1. config package: Defines the service structure using the ServiceConfig struct. This must be initialized first to ensure parameter normalization and default values.
    2. router package: Manages exposed HTTP(S) endpoints. It binds endpoints defined in ServiceConfig, transforms HTTP requests into proxy requests, and converts proxy responses back into HTTP responses.
    3. proxy package: The core processing layer. It transforms requests into one or several backend requests, processes responses, and manages backend connections.

    Other packages provide helpers for encoding, logging, and service discovery.

  3. Use Lura as a Go library to build an API Gateway

    master

    Lura is provided as a Go library that allows you to build custom API Gateways, proxies, or RPC gateways. You can include it in your Go application to aggregate multiple backend services into single endpoints, transform responses, and add middleware (like OAuth or security layers).

    ```go
        package main
    
        import (
            "flag"
            "log"
            "os"
    
            "github.com/luraproject/lura/config"
            "github.com/luraproject/lura/logging"
            "github.com/luraproject/lura/proxy"
            "github.com/luraproject/lura/router/gin"
        )
    
        func main() {
            port := flag.Int("p", 0, "Port of the service")
            logLevel := flag.String("l", "ERROR", "Logging level")
            debug := flag.Bool("d", false, "Enable the debug")
            configFile := flag.String("c", "/etc/lura/configuration.json", "Path to the configuration filename")
            flag.Parse()
    
            parser := config.NewParser()
            serviceConfig, err := parser.Parse(*configFile)
            if err != nil {
                log.Fatal("ERROR:", err.Error())
            }
            serviceConfig.Debug = serviceConfig.Debug || *debug
            if *port != 0 {
                serviceConfig.Port = *port
            }
    
            logger, _ := logging.NewLogger(*logLevel, os.Stdout, "[LURA]")
    
            routerFactory := gin.DefaultFactory(proxy.DefaultFactory(logger), logger)
    
            routerFactory.New().Run(serviceConfig)
        }
        ```
  4. Configure Lura using a JSON configuration file

    master

    Lura uses a JSON file for its configuration. While the underlying viper parser supports other formats, JSON is the recommended format as it is the most thoroughly tested.

    The configuration defines the gateway's identity, network settings, and the routing logic for endpoints and their respective backends.

    {
    	"version": 3,
    	"name": "My lovely gateway",
    	"port": 8080,
    	"timeout": "10s",
    	"cache_ttl": "3600s",
    	"host": [
    		"http://127.0.0.1:8080",
    		"http://127.0.0.2:8000",
    		"http://127.0.0.3:9000",
    		"http://127.0.0.4"
    	],
    	"endpoints": [{
    			"endpoint": "/users/{user}",
    			"method": "GET",
    			"backend": [{
    					"host": [
    						"http://127.0.0.3:9000",
    						"http://127.0.0.4"
    					],
    					"url_pattern": "/registered/{user}",
    					"allow": [
    						"some",
    						"what"
    					],
    					"mapping": {
    						"email": "personal_email"
    					}
    				},
    				{
    					"host": [
    						"http://127.0.0.1:8080"
    					],
    					"url_pattern": "/users/{user}/permissions",
    					"deny": [
    						"spam2",
    						"notwanted2"
    					]
    				}
    			],
    			"concurrent_calls": 2,
    			"timeout": "1000s",
    			"cache_ttl": 3600,
    			"input_query_strings": [
    				"page",
    				"limit"
    			}
    		},
    		{
    			"endpoint": "/foo/bar",
    			"method": "POST",
    			"backend": [{
    					"host": [
    						"https://127.0.0.1:8081"
    					],
    					"url_pattern": "/__debug/tupu"
    				}],
    			"concurrent_calls": 1,
    			"timeout": "1000s",
    			"cache_ttl": 3600
    		}
    	]}
  5. Extend the `router` package

    master
    The router package handles the HTTP(S) service layer. It currently supports implementations using the mux router from net/http and httprouter wrapped in the gin framework. The router layer is designed to be extensible, allowing you to use any HTTP router, framework, or middleware of your choice.
  6. Use the `config` package to define a service

    master
    The config package uses the ServiceConfig struct to describe the entire service. You must initialize this struct before use to ensure all parameters are normalized and default values are applied. The package supports file config parsers and a parser based on the viper library.
  7. Implement and stack Middlewares and Proxies in the `proxy` package

    master

    The proxy package uses two primary interfaces designed to be stacked to create processing chains:

    • Proxy: A function that converts a given context and request into a response.
    • Middleware: A function that accepts one or more proxies and returns a single proxy wrapping them.

    Middlewares generate custom proxies that are chained according to the configuration. These proxies can transform or clone requests and modify received responses.

  8. Configure TLS for the HTTP server

    master

    TLS configuration is handled via the config.TLS object within config.ServiceConfig.

    Key capabilities:

    • mTLS: Enable via EnableMTLS. If enabled, the server will require and verify client certificates using the CA pool defined in CaCerts.
    • Certificates: Provide public/private key paths in Keys or individual PublicKey/PrivateKey fields.
    • Protocol Versions: Specify MinVersion and MaxVersion (e.g., "TLS12", "TLS13").
    • Cipher Suites & Curves: Customize security via CipherSuites and CurvePreferences using uint16 values.
  9. Configure Client TLS settings

    master

    When configuring outbound requests via config.ClientTLS, you can control:

    • AllowInsecureConnections: If true, sets InsecureSkipVerify to true.
    • CaCerts: A list of paths to CA certificates to use for the root CA pool.
    • DisableSystemCaPool: If true, the server will not use the system's default CA pool.
    • ClientCerts: A list of config.ClientTLSCert containing Certificate and PrivateKey paths for client-side authentication.
  10. Configure HTTP Server plugins via extra_config

    master

    You can inject HTTP server plugins into the Lura framework by adding a configuration block under the github_com/devopsfaith/krakend/transport/http/server/handler namespace in your extra_config.

    To use a single plugin, provide a name string. To use multiple plugins in a sequence, provide a list of names in the name field. The plugins will be applied in the order they appear in the list, wrapping the existing handler.

  11. Benchmark Response Property Blacklisting performance

    master
    Performance metrics for the EntityFormatter blacklisting filter. These benchmarks evaluate the cost of filtering response properties based on a blacklist across different numbers of elements and extra fields.
  12. Performance benchmarks for EntityFormatter grouping and mapping

    master

    The EntityFormatter component's performance is measured across different scenarios of response property grouping and mapping.

    • Grouping: Performance remains stable (approx. 298-300 ns/op) regardless of the number of elements (0 to 25 elements).
    • Mapping: Performance scales with the number of elements and extra fields. For example, mapping 5 elements with 25 extra fields takes approximately 339 ns/op, whereas mapping 0 elements with 0 extra fields takes approximately 61.1 ns/op.