Devops
Software Development
Microservices

Simplifying Microservices Observability with Standard Endpoints

Share IconFacebook IconTwitter IconLinkedIn IconPinterest IconWhatsApp Icon

In fast-paced engineering environments, where continuous deployment and distributed ownership are the norm, ensuring system reliability and operational transparency becomes increasingly complex. As organizations move toward microservices architecture to gain agility and scalability, they often trade off simplicity for flexibility. This results in fragmented systems where even the most basic questions become hard to answer:

  • What version of this service is currently running?
  • Is the service healthy and responding as expected?
  • Can I safely deploy, rollback, or route traffic to this instance?

While teams invest heavily in observability stacks, monitoring dashboards, and alerting systems, these tools often rely on application-level signals that may not exist uniformly across services. The absence of a consistent mechanism to verify the runtime state and metadata of a service leads to longer incident response times, harder debugging, and diminished confidence in automated operations.

That’s why a simple but powerful convention is emerging as a best practice in modern microservices: exposing two standard HTTP endpoints—/version and /health—in every service. These endpoints may seem trivial at first glance, but when implemented thoughtfully and consistently, they unlock critical capabilities around deployment tracking, system health checks, observability, and even automation.

In this post, we’ll explore why these two endpoints matter, how they improve operational confidence, and what best practices to follow when implementing them across your architecture.

Make your services more reliable with two lines of code

While modern observability stacks include dashboards, logs, and traces, these endpoints are effective because of their simplicity. They work across languages, teams, and environments. They don’t require agents or integrations. They don’t depend on vendor tools. And yet, they deliver immediate value.

These two endpoints improve monitoring, deployment verification, and incident response without complicating the codebase.

What are the /version and /health endpoints?


microservices

The /version endpoint typically returns metadata about the running instance: the application version, build number or Git commit SHA, deployment environment, and build timestamp. This information helps developers and operators identify which version of the code is active in any given environment. When incidents occur or anomalies are detected, this metadata makes it easier to correlate behavior with deployments and rollbacks.

The /health endpoint, on the other hand, is a lightweight status check. It usually returns a 200 OK when the service is healthy, and a 500 or non-200 when it's not. It's often integrated with infrastructure components like Kubernetes liveness and readiness probes, service meshes, load balancers, and monitoring tools. A well-implemented health check may include checks for upstream dependencies, database connections, configuration validity, or resource saturation, giving a near real-time signal of whether the service is ready to handle traffic.

Together, these endpoints provide foundational observability across all services. They are simple to implement, language-agnostic, and work seamlessly with automation tools, deployment pipelines, and monitoring systems. Importantly, they encourage consistency, making it easier for platform teams to reason about the state of distributed applications at scale.

How the /version endpoint helps

The /version endpoint answers a basic but essential question: what is running?

In complex systems, this is not always obvious. Version mismatches between staging and production can cause bugs that are hard to reproduce. Missing deployments or incorrect rollback behavior may go unnoticed. And debugging incidents without knowing the exact running version adds unnecessary friction.

A /version endpoint solves all of this by making build metadata available over HTTP.

Sample output

json

{

"version": "1.3.7",

"build": "qa"

}

This helps platform teams verify deployments, enables monitoring tools to correlate metrics with build versions, and allows developers to confirm that recent changes have reached their target environments.

Sample implementations of /version

This pattern is easy to implement in any language or framework.

Java (Micronaut)

java

@Controller("/version")

@Secured(SecurityRule.IS_ANONYMOUS)

public class VersionController {

@Value("${version.ver}")

private String version;

@Value("${version.build}")

private String build;

@Get("/")

public VersionDTO getVersion() {

VersionDTO dto = new VersionDTO();

dto.setVersion(version);

dto.setBuild(build);

return dto;

}

}

This code creates a /version endpoint in a Micronaut application. It reads the version and build values from a configuration file (application.yml) and returns them as a JSON object.

yaml

# application.yml

version:

ver: 1.3.7

build: default

# application-dev.yml

version:

build: dev

These configuration files define environment-specific values. The base file sets a default version and build, while the application-dev.yml overrides the build value in development environments.

Python (FastAPI)

python

from fastapi import FastAPI

app = FastAPI()

@app.get("/version")

def version():

return {

"version": "1.3.7",

"build": "qa"

}

This defines a /version route using FastAPI that returns a hardcoded JSON response with version and build metadata.

Node.js (Express)

javascript

const express = require('express');

const app = express();

app.get('/version', (req, res) => {

res.json({

version: "1.3.7",

build: "qa"

});

});

This Express app sets up a GET endpoint at /version that responds with static version and build information in JSON format.

Go (Gin)

go

package main

import (

"github.com/gin-gonic/gin"

"net/http"

)

func main() {

r := gin.Default()

r.GET("/version", func(c *gin.Context) {

c.JSON(http.StatusOK, gin.H{

"version": "1.3.7",

"build": "qa",

})

})

r.Run()

}

This Go application uses the Gin framework to expose a /version endpoint. It returns version and build details as a JSON response.

What about the /health endpoint?

If /version tells us what is running, then /health tells us whether it is working.

The /health endpoint provides a simple status check used by orchestrators, load balancers, and uptime monitors. It can also include deeper diagnostic checks if needed.

Sample output

json

{

"status": "UP"

}

This output is enough for Kubernetes liveness probes, for example. More detailed health endpoints may also include checks on dependencies such as databases or queues.

Sample implementations of /health

Java (Micronaut)

groovy

// build.gradle

implementation("io.micronaut:micronaut-management")

This line adds the Micronaut Management dependency, which enables endpoints like /health.

yaml

# application.yml

endpoints:

health:

enabled: true

sensitive: false

This configuration enables the /health endpoint and makes it publicly accessible (not restricted to authenticated users). Once enabled, Micronaut auto-generates the /health endpoint with built-in checks.

Python (FastAPI)

python

@app.get("/health")

def health():

return { "status": "UP" }

Defines a simple HTTP GET route /health in FastAPI. When called, it returns a JSON response indicating the service is running.

Node.js (Express)

javascript

app.get('/health', (req, res) => {

res.json({ status: "UP" });

});

Registers a /health GET route using Express. It responds with JSON to confirm the app is alive.

Go (Gin)

go

r.GET("/health", func(c *gin.Context) {

c.JSON(http.StatusOK, gin.H{

"status": "UP",

})

})

This Gin framework snippet creates a /health route that returns a 200 OK response with a status indicator.

Why these two endpoints matter

These two simple endpoints bring clarity to environments that are otherwise opaque. Their benefits are immediate and compound over time.

Benefits

  • Deployment clarity

Confirm which version is running in every environment at any time

  • Monitoring integration

/health works seamlessly with Kubernetes, load balancers, and alerting tools

  • Cross-language consistency

One convention that applies to all services, regardless of tech stack

  • Faster debugging

Eliminate guesswork in incident response and postmortems

Rollout strategy

Adding these endpoints does not require refactoring or new dependencies. It can be done incrementally and enforced through templates, CI policies, or review checklists. All new services should include /version and /health from day one to ensure consistency and visibility from the start. For existing services, these endpoints can be introduced gradually during tech-debt cycles or platform upgrade efforts. Continuous Integration (CI) checks can be configured to automatically validate the presence of these endpoints in pull requests, promoting adherence to best practices across teams.

Final thoughts

Microservices bring flexibility, but they also add complexity. As systems grow, keeping them observable becomes essential.

The /version and /health endpoints are not groundbreaking. They are not fancy. But they are consistent, proven, and easy to adopt. They reduce blind spots and improve reliability across every environment.

And the best part? They take only a few lines of code.

Let’s keep our systems observable, dependable, and simple. One endpoint at a time.

Expeed Software

Expeed Software is a global software company specializing in application development, data analytics, digital transformation services, and user experience solutions. As an organization, we have worked with some of the largest companies in the world, helping them build custom software products, automate processes, drive digital transformation, and become more data-driven enterprises. Our focus is on delivering products and solutions that enhance efficiency, reduce costs, and offer scalability.

Devops

Simplifying Microservices Observability with Standard Endpoints

August 11, 2025

Artificial Intelligence

Predictive Analytics in Manufacturing: Use Cases, Tips, and Benefits

August 27, 2025

ai code generation

Evolving as a Developer with AI Assistance

August 29, 2025

Ready to transform your business with custom enterprise web applications?

Contact us to discuss your project and see how we can help you achieve your business goals.