Zuplo logo

Zuplo Changelog

We release improvements, new features, and fixes daily. Follow along here to see the most important updates.

This release introduces significant enhancements to request handling, CLI authentication, logging capabilities, and observability. Key features include a new pre-routing hook for request manipulation before routing, enhanced CLI authentication supporting both Auth0 and API Key methods, custom log fields across all logging plugins, and improved tracing for programmatically invoked policies.

New Features 🎉#

  • Pre-routing hook - Introduces a powerful new hook that allows you to manipulate incoming requests before routing checks are performed. This enables use cases like making URLs case-insensitive or normalizing URL paths. Learn more about pre-routing hooks

  • Custom log fields for all logging plugins - All logging plugins now support a fields option that allows you to append custom fields to every log entry. This enhancement enables better log enrichment and correlation across your observability stack. See custom log fields documentation

  • Tracing for programmatically invoked policies - Policies that are invoked programmatically now include proper tracing information, improving observability and debugging capabilities when policies call other policies within your API gateway. Learn about API monitoring with OpenTelemetry

Bug Fixes 🐛#

  • Enhanced error handling - Strengthened error handling checks for the throwOnError configuration option, ensuring more predictable behavior when errors occur in your API gateway.

Documentation 📚#

  • CLI command consistency - Updated the CLI documentation and commands to consistently use zuplo instead of the shortened zup command, improving clarity and consistency across all documentation.

The new Pre-Routing Hook allows you to manipulate an incoming request before it's checked for routing. For example, if you want all routes to be case insensitive you could just lowercase the URL as it comes into the gateway, as shown below:

runtime.addPreRoutingHook(async (request) => {
  const nr = new Request(request.url.toLowerCase(), request);
  return nr;
});

Another example would be URL path normalization to remove trailing slashes:

runtime.addPreRoutingHook(async (request) => {
  const url = new URL(request.url);
  if (url.pathname.length > 1 && url.pathname.endsWith("/")) {
    url.pathname = url.pathname.slice(0, -1);
    const nr = new Request(url, request);
    return nr;
  }
  return request;
});

Keep in mind that this will run on all requests so the code you use here needs to be appropriately performant and aware it can generate weird downstream effects by changing URLs and headers.

The method is async but reading and manipulating the request body is not recommended for performance reasons.

A new fields option is now available across all logging plugins. This addition enables you to append arbitrary custom fields to each log entry, providing additional context and information in your logs.

For example, using our Google Cloud Logging plugin:

import {
  RuntimeExtensions,
  GoogleCloudLoggingPlugin,
  environment,
} from "@zuplo/runtime";

export function runtimeInit(runtime: RuntimeExtensions) {
  runtime.addPlugin(
    new GoogleCloudLoggingPlugin({
      logName: "projects/my-project/logs/my-api",
      serviceAccountJson: environment.GCP_SERVICE_ACCOUNT,
      fields: {
        myCustomField: "value",
        anotherCustomField: "value2",
      },
    }),
  );
}

You can use this feature to include relevant metadata, application-specific details, or contextual information that may be useful for debugging or analysis purposes.

This release includes improvements to logging stability and performance.

Bug Fixes 🐛#

  • Fixed OpenTelemetry fetch instrumentation issue - Resolved an issue with OpenTelemetry outgoing fetch instrumentation that could cause unexpected behavior in distributed tracing. This fix ensures proper trace context propagation for outgoing HTTP requests.

  • Improved log ordering - Fixed an issue where logs could appear out of order in certain scenarios. Logs now maintain their correct chronological sequence for better debugging and monitoring.

The Zuplo Identity Token is a new feature that allows developers to create a JWT token that uniquely and securely identifies their Zuplo API. This token can be used to authenticate downstream services or third-party APIs, enabling secure communication between services without the need for additional authentication mechanisms or sharing of sensitive credentials.

The Zuplo Identity Token is a JSON Web Token (JWT) that contains information about the Zuplo API that it represents. This token is signed by Zuplo and can be verified by downstream services or third-party APIs to ensure its authenticity and integrity.

The token contains claims for the Zuplo account, project, and deployment that can be used to uniquely identify the API and its associated resources. See the Zuplo Identity Token documentation for more information.

Using the Token#

Developers can access the Zuplo Identity Token in their code by calling the ZuploServices API. A custom audience can be provided to the token to ensure that it is only usable by the intended downstream service. Multiple tokens with different audiences can be created and caching is managed by Zuplo to ensure high performance.

import { ZuploServices, ZuploContext, ZuploRequest } from "@zuplo/runtime";

export default async function handler(
  request: ZuploRequeset,
  context: ZuploContext,
) {
  const idToken = await ZuploServices.getIDToken(context, {
    audience: "https://my-api.example.com",
  });

  const response = await fetch("https://my-api.example.com", {
    headers: {
      Authorization: `Bearer ${idToken}`,
    },
  });
}

Federated Identity increases the security of your Zuplo API by removing the need to share sensitive service account keys with your Zuplo API. Instead, Zuplo will use the Zuplo Identity Token to authenticate with Google Cloud Services on your behalf.

A new policy has been added to Zuplo that enables Federated Identity with Google Cloud Services. By utilizing this policy developers can secure their GCP API or other Google Cloud Resources (Storage, Pub/Sub, etc.) with GCP IAM and allow Zuplo to call these services on their behalf.

Federated Identity with GCP is available as a paid-addon to customers on enterprise plans. Contact your account manager or sales@zuplo.com to inquire about pricing.

For more information on how to configure Federated Identity with GCP, see the Federated Identity with GCP documentation.