DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your GraphQL API with Vigilmon (Uptime + Query Health Checks)

GraphQL APIs have a different monitoring profile than REST APIs. All queries go to a single endpoint (usually /graphql), but a 200 response does not mean your queries are working — it could be returning a {"errors": [...]} payload for every request.

This guide explains how to monitor GraphQL APIs with Vigilmon and what to watch for beyond basic uptime.

Why GraphQL Monitoring Is Different

With REST:

  • GET /api/users returning 200 means users are accessible
  • GET /api/products returning 503 means products are down

With GraphQL:

  • POST /graphql returning 200 could mean success OR a partial success with errors
  • The HTTP layer always returns 200 — errors are in the response body
  • Schema introspection queries can succeed while real queries fail

This means a simple "check for 200" monitor misses GraphQL-specific failures.

Step 1: Add a Health Introspection Query

The simplest GraphQL health check is an introspection query:

POST /graphql
Content-Type: application/json

{"query": "{ __typename }"}
Enter fullscreen mode Exit fullscreen mode

This returns {"data": {"__typename": "Query"}} on a healthy server. If the server is completely down, it returns a non-200 or a network error.

Configure Vigilmon to:

  • URL: https://your-api.com/graphql
  • Method: POST
  • Headers: Content-Type: application/json
  • Body: {"query": "{ __typename }"}
  • Expected status: 200

Step 2: Add a Dedicated Health Query

Add a dedicated health query to your schema:

type Query {
  health: HealthStatus!
}

type HealthStatus {
  status: String!
  database: String!
  version: String!
}
Enter fullscreen mode Exit fullscreen mode

Implementation (Node.js/Apollo):

const resolvers = {
  Query: {
    health: async () => {
      let dbStatus = "ok";
      try {
        await prisma.$queryRaw`SELECT 1`;
      } catch (e) {
        dbStatus = "error";
      }

      return {
        status: dbStatus === "ok" ? "ok" : "degraded",
        database: dbStatus,
        version: process.env.APP_VERSION || "unknown",
      };
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

Then add a monitor for:

POST /graphql
Body: {"query": "{ health { status database } }"}
Enter fullscreen mode Exit fullscreen mode

Step 3: Check Response Body Content

Vigilmon can check that the response contains a specific string. Configure it to verify the response contains "status":"ok":

  • Expected response: contains "status":"ok"

This catches the case where GraphQL returns 200 but the health query returns an error.

Step 4: Add a REST Health Endpoint

If your GraphQL server is built with Apollo Server or similar, add a REST health endpoint alongside your GraphQL endpoint:

// Express + Apollo Server
app.get("/health", (req, res) => {
  res.json({ status: "ok", graphql: "ok" });
});
Enter fullscreen mode Exit fullscreen mode

Monitor https://your-api.com/health for a simpler uptime check, and the GraphQL endpoint separately for query health.

Setting Up in Vigilmon

  1. Sign up at vigilmon.online — free for 50 monitors
  2. Add your /graphql monitor with POST method and the health query body
  3. Add your /health REST endpoint if available
  4. Set check interval to 1 minute
  5. Configure Slack or email alerts

Monitoring Authenticated GraphQL

If your GraphQL API requires authentication, generate a long-lived monitoring token and configure Vigilmon with the Authorization header:

// Apollo Server: add a bypass for the monitoring token
const server = new ApolloServer({
  context: ({ req }) => {
    const token = req.headers.authorization?.split("Bearer ")[1];

    if (token === process.env.MONITORING_TOKEN) {
      return { user: { id: "monitoring", role: "admin" } };
    }

    // Normal auth logic
    return authenticateToken(token);
  },
});
Enter fullscreen mode Exit fullscreen mode

Common GraphQL Failure Modes

  1. N+1 query explosion — resolvers trigger too many database queries; the server responds slowly then times out
  2. Schema breaking changes — a resolver returns null where the schema expects a non-null type
  3. Subscription handler failure — realtime subscriptions stop delivering updates
  4. Persisted query cache miss — if you use APQ, a Redis/cache failure returns 400s
  5. Rate limiter too aggressive — legitimate monitoring queries get blocked

External uptime monitoring catches the first two from the user perspective. For subscriptions and cache failures, you need application-level monitoring.

Multiple Environments

Run separate monitors for development, staging, and production GraphQL endpoints:

  • Production: https://api.yourapp.com/graphql — alert on 1 failure
  • Staging: https://staging-api.yourapp.com/graphql — alert on 3 failures

This lets you catch regressions in staging before they hit production.

Monitor your GraphQL API at vigilmon.online — free, no credit card, 5-minute setup.

Top comments (0)