Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Checkybot Laravel Laravel Package

marin-solutions/checkybot-laravel

Laravel integration for CheckyBot that makes it simple to add uptime, cron and health monitoring to your application. Connect your app with minimal configuration and get timely alerts when checks fail, so you can catch issues before they affect users without adding complexity to your codebase.

View on GitHub
Deep Wiki
Context7

Getting Started

Checkybot is a Laravel package for defining HTTP/API checks that a Checkybot server executes on your behalf. The PHP side is a fluent definition layer; the actual request and assertion evaluation happen server-side. That split matters for everything below — your Laravel app describes what to check, the server does the checking.

Install and publish config first:

composer require checkybot/checkybot
php artisan vendor:publish --tag=checkybot-config

Then confirm two things before writing any checks:

  1. Credentials/endpoint in config/checkybot.php (or the matching env vars) point at a reachable Checkybot server.
  2. Server version. The v0.2.3 release introduces ApiCheck::source(), which is only honoured by a server with source support. A client newer than the server will silently ignore the chaining rather than fail loudly — see Gotchas.

Where to look first: the package's check-definition classes (the ApiCheck builder) and the config file. The builder is the whole public API surface; there is very little else to learn.

First use case — the one you should get working before touching chaining:

ApiCheck::make('Health endpoint')
    ->url('https://api.example.com/health')
    ->method('GET')
    ->assertStatus(200)
    ->assertJsonPath('status', 'ok');

Register it wherever the package expects checks (a service provider, a dedicated checks.php, or a scheduled command — check the package's own docs for the registration point, as this is the part most likely to differ between minor versions). Run it, confirm it appears on the server, then move on to source().

Implementation Patterns

Basic checks: assert narrowly, name descriptively

The cheapest mistake to make is an over-broad assertion — assertStatus(200) alone on an endpoint that returns 200 with an error body. Pair a status assertion with at least one body assertion, and name checks so an alert is self-explanatory:

ApiCheck::make('Checkout: cart totals endpoint returns priced cart')
    ->url('https://api.example.com/v1/cart/{cart_id}')
    ->assertStatus(200)
    ->assertJsonPath('total.currency', 'GBP');

Chained checks with source() — the v0.2.3 pattern

ApiCheck::source($url, $path) exists to solve the "I need an ID/token/slug from a previous response" problem. The server calls the source URL, reads $path out of the response, and substitutes it into {source} in both the check URL and assertion expected values.

ApiCheck::make('Order detail resolves for a real order')
    ->source('https://api.example.com/v1/orders?limit=1', 'data.0.id')
    ->url('https://api.example.com/v1/orders/{source}')
    ->assertStatus(200)
    ->assertJsonPath('data.id', '{source}');

Three things this unlocks, in rough order of day-to-day value:

1. Referential integrity checks. Asserting that the ID you fetched is the ID you got back is a genuinely useful smoke test — it catches routing/tenant-isolation bugs that a fixed-ID check never would.

2. Fixture-free checks. No hardcoded IDs that rot when a seed changes. The source resolves a live value each run.

3. Assertion-level substitution. Because {source} is replaced in expected values too, you can assert equality against a dynamically-derived value without duplicating the path in your PHP:

->source('https://auth.example.com/v1/me', 'tenant.slug')
->url('https://api.example.com/v1/tenant/{source}/settings')
->assertJsonPath('tenant.slug', '{source}');

Use that form deliberately — an assertion that X == X because both sides came from the same source is a tautology and tests nothing about the tenant endpoint. Prefer asserting derived facts (a status, a permission flag, a related field) rather than echo-back equality.

Workflow: keep sources cheap and stable

Treat each source() call as a dependency with its own latency and failure mode. Favour:

  • A single, cheap source per check rather than a chain of three.
  • Sources that are read-mostly and idempotent — never point a source at a POST/mutation endpoint.
  • Sources on the same host as the check where possible, so a single outage doesn't produce two unrelated-looking alerts.

Integration tips

  • Local development: if you can't reach a source-supporting server, keep your existing non-chained checks in one file and put chained checks in a separate definition so you can disable them wholesale without commenting out code.
  • Version-pin the client once you adopt source(). A ^0.2 constraint is reasonable; a floating constraint against a package whose behaviour is server-negotiated is asking for a silent regression.
  • Staging first. Chained checks are the kind of thing that passes in staging (small, predictable data) and gets flaky in production (pagination order, empty result sets). Validate against production-shaped data before relying on the alert.

Gotchas and Tips

The server-support footgun

The release note says it plainly: needs a Checkybot server with source support. What it doesn't say is what an unsupported server does with {source}. Assume the worst case — the placeholder is passed through literally as a URL segment (/v1/orders/%7Bsource%7D), the request 404s, and you get an alert that looks like an application bug rather than a version mismatch.

Mitigations, in order:

  1. Verify server support explicitly before rolling out chained checks. Hit the server's version/health endpoint, or check its docs, and record the minimum version somewhere in your repo (README or an UPGRADING.md note).
  2. Add one canary check whose source is a trivially-stable endpoint and whose assertion compares against a known literal. If that fails while your non-chained checks pass, you've isolated the problem to server support.
  3. Don't mix the migration into an unrelated PR. Deploy the client bump and the first chained check separately so a rollback is unambiguous.

Path syntax is server-side, not PHP-side

$path in source(url, path) is resolved by the server, so it is not Laravel's Arr::get() and not dot-notation-identical to anything you're used to. data.0.id may or may not be the array-index syntax the server expects — it could be data[0].id, a JSONPath like $.data[0].id, or something bespoke. Test one path against real data before writing twenty checks with the same syntax.

Practical debugging: temporarily assert the raw path in a throwaway check and read the failure output. A "source resolved to empty" error usually means the path is wrong, not that the endpoint is down.

Empty or ambiguous source results

The nastiest failure mode is a source that succeeds but returns nothing useful:

  • orders?limit=1 returns {"data": []} → path resolves to null/empty → check URL becomes /v1/orders/ (trailing slash) → you're now testing your collection endpoint by accident, and it may well return 200, so the check passes while testing nothing.
  • A source returning multiple rows where your path picks [0] gives you a different value each run. The check becomes non-deterministic and will eventually page you at 3am for no reason.

Guard against both: prefer sources with a deterministic, single result (a /me, /config, /health-style endpoint), and be suspicious of any check where a passing result doesn't clearly correspond to a real assertion.

Timeouts and cascading failure

Chained checks have two round trips. If the source times out, the check fails for a reason unrelated to the endpoint under test — and both alerts will likely fire together, doubling noise. Where the server exposes timeouts or retry settings, tune the source fetch tighter than the check itself, and make sure your alert routing groups related checks rather than paging per-check.

Secrets in source URLs

Source URLs are often auth or token-issuing endpoints. Don't inline credentials into source() arguments — read them from config/env and let them flow through, so the definition stays safe to commit and safe to display in a check dashboard. The same applies to expected values: a {source}-substituted assertion is fine, a hardcoded API key in an assertion is not.

Extension points

Because the substitution happens server-side, you cannot debug it with dd() or Xdebug through the package. Your levers are:

  • Verbose/log output from the package or the server's response payload for a failing check.
  • The check definition itself — split a failing chained check into a standalone source check plus a fixed-value check to identify which half broke.
  • Config-level toggles for timeouts, base URLs, and any per-environment overrides the published config exposes. Read the published config file once, end to end; it's short and it documents behaviour that the release notes don't.

Version-pinning summary

Concern Advice
Client constraint Pin to ^0.2, upgrade deliberately
Server support Verify before adopting source()
Rollout Canary chained check, separate deploy from the client bump
Rollback Keep chained checks in a separable definition block

The v0.2.3 feature is a small API addition with a large operational dependency. The code is one line; the risk is entirely in the version pairing and in path syntax you can't introspect from PHP. Get the canary right and chained checks are a genuine upgrade over hardcoded IDs.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib