Monitoring Shopify App Health Without the Boilerplate (Thanks Gadget)
Marcus Wright

Marcus Wright @marcus_wright__

About: backend dev who builds clean, scalable APIs that actually work solving puzzles & cutting through bad docs like a pro

Joined:
Jul 2, 2025

Monitoring Shopify App Health Without the Boilerplate (Thanks Gadget)

Publish Date: Jul 30
6 0

I’m a backend dev based in Chicago, and like most backend folks, I live for clean data flows and low-friction tools. Recently, I wanted to build something small but useful — a lightweight internal tool to monitor the health of a Shopify app I’ve been working on. Stuff like webhook failures, slow response times, and retry logic.

The goal wasn’t a full observability suite, just a simple dashboard that could tell me: is the app alive, or is it quietly failing in the background?

Why Gadget?
I found Gadget while deep in the Shopify docs rabbit hole, trying to figure out how to scaffold an embedded app without setting up the whole stack manually. I’ve spun up enough Node/Express/Postgres apps in my life. I wasn’t trying to waste another weekend wiring up OAuth and migrations.

Gadget came with:

  • Shopify auth already wired in
  • A built-in Postgres DB with a schema UI + code access
  • Prebuilt API routes
  • File storage + background jobs
  • TypeScript all the way down

So I gave it a shot.

What I Built
I created a small tool that logs request metrics from my Shopify app: response times, status codes, and webhook delivery outcomes. The goal was to see patterns over time and catch flakiness early.

Step 1: Create a Model
Inside Gadget’s data modeling UI, I defined a RequestLog model with the following fields:

model RequestLog {
id: ID!
shop: ShopifyShop @relation
path: String
statusCode: Int
responseTimeMs: Int
timestamp: DateTime @default(now())
}

I love that I could tweak this either via the UI or by editing the .schema file directly. Once saved, Gadget automatically gives you API access and a full CRUD interface for the model.

Step 2: Capture the Data
Inside my Shopify app, I routed all outgoing requests through a small wrapper that records timing and outcome, then sends the data to my Gadget backend using the built-in API routes:

async function logRequest(path, statusCode, responseTimeMs) {
await fetch(${process.env.GADGET_API_URL}/api/requestLogs, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: Bearer ${session.token}, // Gadget handles session
},
body: JSON.stringify({
path,
statusCode,
responseTimeMs,
timestamp: new Date().toISOString(),
}),
});
}

Simple. No need to manually build an auth layer or endpoint.

Step 3: Build a Dashboard
I exposed a GET /api/requestLogs route in Gadget and filtered by store + recent logs. This lets me pull the last N requests and render them in a basic table or chart.

Here's what a basic GET handler looks like in Gadget:

export async function get(request, { session, api }) {
const shopId = session.shopId;
const logs = await api.requestLog.findMany({
filter: { shop: { equals: shopId } },
sort: { timestamp: "Descending" },
first: 100,
});

return {
statusCode: 200,
body: logs,
};
}

It’s all serverless, and Gadget handles execution and scaling behind the scenes.

Takeaways
I’ve worked with Heroku, Supabase, Firebase, and even self-hosted stacks. Gadget feels different since its more opinionated, but in a way that actually saves time. If you're building a backend-heavy app and don’t want to start from zero every time, it's a solid option.

Pros:

  • Fastest setup I’ve had for an authenticated, DB-backed app
  • Schema modeling + real code
  • TypeScript all the way through
  • Background job support is built-in (though I didn’t need it for this one)

Cons:

  • Some limits if you want to customize every layer
  • Still maturing as a platform (but very responsive team)

If you’re a backend dev building on Shopify, or just tired of spinning up the same boilerplate, give Gadget a look.

🔗 DM me on X/Twitter if you’re building anything similar or want to trade horror stories about bad API docs.

Happy building.

Comments 0 total

    Add comment