Skip to content

Frontman is an open-source API gateway written in Go that allows you to manage your microservices and expose them as a single API endpoint. It acts as a reverse proxy and handles requests from clients, routing them to the appropriate backend service.

License

Notifications You must be signed in to change notification settings

hyperioxx/frontman

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Logo

Frontman

Frontman is an open-source API gateway written in Go that allows you to manage your microservices and expose them as a single API endpoint. It acts as a reverse proxy and handles requests from clients, routing them to the appropriate backend service.

Frontman provides a simple, flexible, and scalable solution for managing microservices. It includes features such as and automatic health checks, making it easy to manage and maintain your API gateway and backend services.

With Frontman, you can easily add new backend services, update existing ones, and remove them, without affecting the clients. Frontman also provides an HTTP API for managing backend services, making it easy to automate the management of your API gateway.

Frontman is designed to be highly available and fault-tolerant. It uses Redis as a data store for managing backend services, ensuring that your services are always available and up-to-date. It also supports distributed deployments, allowing you to scale horizontally as your traffic and service requirements grow.

Overall, Frontman is a powerful and flexible API gateway that simplifies the management of microservices, making it easier for developers to build and maintain scalable and reliable API endpoints.

 

Go Report Card GitHub license GitHub go.mod Go version

Glossary

Features

  • Reverse proxy requests to backend services
  • Dynamic backend service configuration using Yaml, Redis or MongoDB as a backend database
  • Automatic refresh of connections to upstream targets with configurable timeouts and maximum idle connections
  • TLS encryption for secure communication with clients
  • Option to strip the service path from requests before forwarding to upstream targets
  • Written in Go for efficient performance and concurrency support
  • Plugin system to modify requests and responses before they are sent to or received from the backend service

Usage

Configuration

Env Variables

Frontman is configured using environment variables. The following variables are supported:

Environment Variable Description Default
FRONTMAN_SERVICE_TYPE The service type to use yaml
FRONTMAN_SERVICES_FILE The path to the services file services.yaml
FRONTMAN_REDIS_NAMESPACE The namespace used to prefix all Redis keys frontman
FRONTMAN_REDIS_URL The URL of the Redis instance used for storing service registry redis://localhost:6379
FRONTMAN_MONGO_URL The URL of the Mongo instance used for storing service registry mongodb://localhost:27017
FRONTMAN_MONGO_DB_NAME The name of the MongoDB database where the service registry is stored. frontman
FRONTMAN_MONGO_COLLECTION_NAME The name of the MongoDB collection where the service registry is stored. services
FRONTMAN_API_ADDR The address and port on which the API should listen for incoming requests 0.0.0.0:8080
FRONTMAN_API_SSL_ENABLED Whether or not the API should use SSL/TLS encryption false
FRONTMAN_API_SSL_CERT The path to the API SSL/TLS certificate file
FRONTMAN_API_SSL_KEY The path to the API SSL/TLS key file
FRONTMAN_GATEWAY_ADDR The address and port on which the gateway should listen for incoming requests 0.0.0.0:8000
FRONTMAN_GATEWAY_SSL_ENABLED Whether or not the gateway should use SSL/TLS encryption false
FRONTMAN_GATEWAY_SSL_CERT The path to the gateway SSL/TLS certificate file
FRONTMAN_GATEWAY_SSL_KEY The path to the gateway SSL/TLS key file
FRONTMAN_LOG_LEVEL The log level to use info

Frontman Configuration File

This describes the structure and options of the Frontman configuration file. This file is used to configure the Frontman API gateway and services.

The configuration file is written in YAML format and is structured as follows:

global:
  service_type: "my_service"
  services_file: "services.yaml"
  redis_uri: "redis://localhost:6379"
  redis_namespace: "my_service"
  mongo_uri: "mongodb://localhost:27017"
  mongo_db_name: "my_db"
  mongo_collection_name: "my_collection"
api:
  addr: ":8080"
  ssl:
    enabled: true
    cert: "/path/to/cert.pem"
    key: "/path/to/key.pem"
gateway:
  addr: ":8081"
  ssl:
    enabled: false
logging:
  level: "debug"
plugins:
  enabled: true
  order:
    - "/path/to/plugin1.so"
    - "/path/to/plugin2.so"

Global Section

The global section contains global configuration options that apply to both the API and Gateway.

Key Description Default Value
service_type The type of service registry used to store backend services. Valid options are yaml and redis. yaml
services_file The path to the YAML file used to store backend services when using the yaml service registry. services.yaml
redis_namespace The namespace used to prefix all Redis keys when using the redis service registry. frontman
redis_uri is a string representing the URI of the Redis server that the application will use to store and retrieve backend services data. redis://localhost:6379
mongo_uri is a string representing the URI of the MongoDB server that the application will use to store and retrieve backend services data. mongodb://localhost:27017
mongo_db_name is a string representing the name of the MongoDB database where the backend services will be stored. frontman
mongo_collection_name is a string representing the name of the MongoDB collection where the backend services will be stored. services

API Section

The api section contains configuration options for the Frontman API.

Key Description Default Value
addr The address on which the Frontman API will listen. 0.0.0.0:8080
ssl.enabled Whether or not the API should use SSL/TLS encryption. false
ssl.cert The path to the API SSL/TLS certificate file.

Gateway Section

The gateway section contains configuration options for the Frontman Gateway.

Key Description Default Value
addr The address on which the Frontman Gateway will listen. 0.0.0.0:8000
ssl.enabled Whether or not the Gateway should use SSL/TLS encryption. false
ssl.cert The path to the Gateway SSL/TLS certificate file.

Logging Section

The logging section contains configuration options for the Frontman logging.

Key Description Default Value
level The log level of the Frontman logging. Valid options are debug, info, warn, error, and fatal. info

Starting Frontman

To start Frontman, you can download the latest release binary for your platform from the releases page or build it from source.

Building from Source

To build the application from source, make sure you have Go installed on your system.

Clone the repository:

$ git clone https://github.com/Frontman-Labs/frontman.git
$ cd frontman

Build the binaries:

$ make all

This will build all programs defined in the cmd directory and place the resulting binaries in the bin directory.

(Optional) Clean up the binaries:

$ make clean

This will remove all binaries from the bin directory.

Running Frontman Locally

After downloading or building Frontman, you can run it locally by providing a configuration file with the -config flag. The configuration file specifies the configuration options. Before running Frontman, make sure to review the configuration file to understand the options and backend service configurations.

To start Frontman, navigate to the directory containing the binary and run the following command:

$ ./frontman -config /path/to/config.yml

Replace /path/to/config.yml with the actual path to your configuration file. This command will start Frontman with the specified configuration options. You can then make requests to Frontman's API or Gateway at the specified endpoints to have them forwarded to the configured backend services.

Frontman does not provide a way to configure backend services via the configuration file. Instead, you can use Frontman's API to add, update, or remove backend services dynamically. The API allows you to manage backend services in real-time without having to restart Frontman.

To add a backend service, send a POST request to /api/services with the backend service configuration in the request body. To update a backend service, send a PUT request to /api/services/{name} with the updated backend service configuration in the request body. To remove a backend service, send a DELETE request to /api/services/{name}.

Once backend services have been defined and stored in the service registry, Frontman can be configured to use that service registry by specifying the appropriate service type and configuration parameters in the global config file.

Running Frontman in Docker

Frontman can also be run as a Docker container. Here's an example command to start Frontman in Docker, assuming your Redis instance is running on localhost:

$ docker run -p 8080:8080 hyperioxx/frontman:latest

This command starts a new container, maps port 8080 on the host to port 8080 in the container

Managing Backend Services

Frontman uses various storage systems to manage backend service configurations. Backend services are represented as JSON objects and stored in a data storage system. Here's an example of a backend service configuration:

{
  "name": "test_service",
  "scheme": "http",
  "upstreamTargets": [
    "http://localhost:8080"
  ],
  "path": "/api/test",
  "domain": "localhost",
  "healthCheck": "/health",
  "retryAttempts": 3,
  "timeout": 10,
  "maxIdleConns": 100,
  "maxIdleTime": 30,
  "stripPath": true,
  "loadBalancerPolicy": { 
    "type": "",
    "options": {
      "weights": []
    }
  }
}

Supported Load Balancer types:

  • Random

      "loadBalancerPolicy": { 
        "type": "random"
      }
  • Round-robin

      "loadBalancerPolicy": { 
        "type": "round_robin"
      }
  • Weighted Round-robin

    "loadBalancerPolicy": { 
      "type": "weighted_round_robin",
      "options": {
        "weights": [1, 2, 3]
      }
    }
  • Least Connection

      "loadBalancerPolicy": { 
        "type": "least_conn"
      }
  • Weighted Least Connection

      "loadBalancerPolicy": { 
        "type": "weighted_least_conn"
        "options": {
          "weights": [1, 2, 3]
      }

You can add, update, and remove backend services using the following REST endpoints:

  • GET /services - Retrieves a list of all backend services
  • GET /health - Performs a health check on all backend services and returns the status of each service
  • POST /services - Adds a new backend service
  • PUT /services/{name} - Updates an existing backend service
  • DELETE /services/{name} - Removes a backend service

Adding authentication to backend services

Frontman currently supports two methods of authentication: JWT tokens and Basic Auth. Authentication can be configured for each backend service separately using the auth configuration option:

  • Basic Auth with Username and Password In config:
  # .. backend config
  auth:
    type: "basic"
    basic:
      username: "test"
      password: "test"
  • Basic Auth with username and password environment variable:
  # .. backend config
  auth:
    type: "basic"
    basic:
      usernameEnvVariable: "API_USERNAME"
      passwordEnvVariable: "API_PASSWORD"
  • Basic Auth with username and password stored in credentials file:
   # .. backend config
  auth:
    type: "basic"
    basic:
      credentialsFile: "credentials.yaml"

credentials.yaml:

username: "filetest"
password: "filetest"
  • JWT Auth:
  # .. backend config
  auth:
    type: "jwt"
    userDataContextKey: "user" # Header for storing user claims
    jwt:
      audience: <audience>
      issuer: <issuer>
      keysUrl: <jwks_uri>

URL Rewrite

The API Gateway now supports URL rewriting, allowing you to modify the requested URL path before forwarding the request to the upstream service. To use this feature, you'll need to provide two additional fields in the BackendService configuration:

  • RewriteMatch: A regular expression pattern that matches the part of the URL path you want to rewrite.
  • RewriteReplace: The string that should replace the matched part of the URL path.

Example yaml file configuration:

  - name: example-service
    domain: example.com
    path: /api
    scheme: https
    stripPath: false
    rewriteMatch: "/api/([^/]+)/v1"
    rewriteReplace: "/api/$1/v2"
    upstreamTargets:
      - https://upstream.example.com

In this example, any request with a URL path that matches the pattern /api/([^/]+)/v1 will be rewritten to use /api/<captured_group>/v2 before being forwarded to the upstream service. This allows you to seamlessly redirect requests to a new API version or change the URL structure as needed.

Please note that the URL rewriting takes place after the stripPath processing. If stripPath is set to true, the provided rewriteMatch and rewriteReplace patterns should take that into account.

Frontman Plugins

Frontman allows you to create custom plugins that can be used to extend its functionality. Plugins are implemented using the FrontmanPlugin interface, which consists of three methods:

  • Name(): returns the name of the plugin.
  • PreRequest(): is called before sending the request to the target service. It takes in the original request, a ServiceRegistry, and a Config. An error is returned if the plugin encounters any issues.
  • PostResponse(): is called after receiving the response from the target service. It takes in the response, a ServiceRegistry, and a Config. An error is returned if the plugin encounters any issues.
  • Close(): is called when the plugin is being shut down. An error is returned if the plugin encounters any issues.

To create a plugin, implement the FrontmanPlugin interface in a Go package. Then, add the plugin to the Frontman configuration file.

Here is an example of a simple Frontman plugin:

type FrontmanPlugin struct {}

func (p *FrontmanPlugin) Name() string {
    return "Example Plugin"
}

func (p *FrontmanPlugin) PreRequest(req *http.Request, sr service.ServiceRegistry, cfg config.Config) error {
    // Modify the request before sending it to the target service
    return nil
}

func (p *FrontmanPlugin) PostResponse(resp *http.Response, sr service.ServiceRegistry, cfg config.Config) error {
    // Modify the response before sending it back to the client
    return nil
}

func (p *FrontmanPlugin) Close() error {
    // Cleanup resources used by the plugin
    return nil
}

To compile a Go plugin, you first need to implement the FrontmanPlugin interface in a Go package. Once your plugin is implemented, you can compile it using the following command:

go build -buildmode=plugin -o example.so example.go

This will produce a shared library named example.so that can be loaded dynamically at runtime.

After compiling the plugin, you need to update the Frontman configuration file to load the plugin. In the PluginConfig section of the configuration file, set enabled to true and add the path to the plugin library to the order array. For example:

plugin:
  enabled: true
  order:
    - "/path/to/example.so"

In this example, the plugin library is located at /path/to/example.so. If you have multiple plugins, you can specify the order in which they should be loaded by adding their paths to the order array.

Once you have updated the configuration file, restart Frontman to load the new plugins. Your plugin should now be loaded and its PreRequest and PostResponse methods will be called for each request.

Contributing

If you'd like to contribute to Frontman, please fork the repository and submit a pull request. We welcome bug reports, feature requests, and code contributions.

License

Frontman is released under the GNU General Public License. See LICENSE for details.

About

Frontman is an open-source API gateway written in Go that allows you to manage your microservices and expose them as a single API endpoint. It acts as a reverse proxy and handles requests from clients, routing them to the appropriate backend service.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages