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

Symfony Monday Api Bundle Laravel Package

gponty/symfony-monday-api-bundle

A Symfony bundle for integrating the Monday.com API into your applications. It provides service configuration and convenient access to Monday.com boards, items, and GraphQL requests within Symfony's dependency injection container.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalize: this is a Symfony bundle, not a Laravel package. There is no service provider, no publishable config/monday.php, no facade. It ships a Bundle subclass, a DI extension, and YAML service definitions that assume symfony/framework-bundle is booting the container. In a Laravel app you get none of that wiring for free — you either bridge it manually or lift the underlying client out and bind it yourself. Release 1.20 (SF 8) reinforces this: the only change is Symfony 8 compatibility, i.e. the package's roadmap is driven by Symfony's release cycle, not Laravel's.

Steps to get moving:

  1. composer require gponty/symfony-monday-api-bundle — but before you commit, check composer.json in the tag you install. 1.20 adds Symfony 8 support, and Symfony 8 is PHP 8.4+; confirm the php and symfony/* constraints resolve against your app's composer.json before you build anything.
  2. Open vendor/gponty/symfony-monday-api-bundle and read three files: the *Bundle.php class, DependencyInjection/Configuration.php (this is the authoritative list of config keys — token, API version, endpoint, maybe default board IDs), and Resources/config/services.yaml (service IDs and constructor arguments).
  3. Determine whether the actual GraphQL/HTTP client is a separate package (e.g. gponty/monday-api). If so, depend on that directly and skip the bundle entirely — it's the cleaner path in Laravel, and it insulates you from Symfony major bumps like this one.
  4. Add config plus a container binding.

Minimal Laravel bridge:

// config/monday.php
return [
    'token'    => env('MONDAY_API_TOKEN'),
    'version'  => env('MONDAY_API_VERSION', '2024-10'),
    'endpoint' => 'https://api.monday.com/v2',
    'boards'   => [
        'leads' => env('MONDAY_BOARD_LEADS'),
        'deals' => env('MONDAY_BOARD_DEALS'),
    ],
];
// app/Providers/MondayServiceProvider.php
public function register(): void
{
    $this->app->singleton(MondayClient::class, fn () => new MondayClient(
        token: config('monday.token'),
        apiVersion: config('monday.version'),
        endpoint: config('monday.endpoint'),
    ));
}

First use case to exercise: read a board, then create an item from a form submission. That touches auth, a query, a mutation, and column-value serialization — the four things you will handle every day with this API.

Implementation Patterns

Wrap the client; don't sprinkle it. Create App\Services\Monday\BoardRepository and ItemRepository with intent-revealing methods (createLead(array $data), moveItemToGroup(string $itemId, string $groupId)). The bundle's client is transport. Keep GraphQL strings out of controllers and jobs.

Config-driven board IDs. Board IDs differ per environment. Keep them in config/monday.php and inject via config — never hardcode them into queries.

GraphQL with reusable fragments. Fetch and cache board schema:

$query = <<<'GQL'
query ($boardId: ID!) {
  boards(ids: [$boardId]) {
    columns { id title type settings_str }
    groups  { id title }
  }
}
GQL;

Columns change monthly at most; querying them on every write is wasted complexity budget. Cache for hours.

Column values are JSON strings. Nearly every mutation takes column_values: String! containing json_encode([...]). Build a small ColumnValues value object that knows the shape per type: status ({"label":"Done"} or {"id":"1"}), date (Y-m-d), people ({"personsAndTeams":[{"id":123,"kind":"person"}]}), phone ({"phone":"...","countryShortName":"US"}), email, dropdown ({"ids":[1,2]}). This is where the majority of your bugs will live.

Prefer webhooks over polling. Monday pushes item and column changes. In Laravel: a route at /webhooks/monday, an exception from VerifyCsrfToken, and a subscription command/job that calls the create_webhook mutation. The subscription handshake (Monday POSTs {"challenge": "..."} and expects it echoed back verbatim) belongs in its own early-return path, not in business logic.

Queue every write. Wrap mutations in jobs with $tries = 3, exponential backoff(), and middleware([WithoutOverlapping::class]) keyed by item ID. Monday's complexity budget is per-minute and per-token; a bulk import will 429 you quickly.

Idempotency. Persist the Monday item ID and any webhook event ID behind a unique index before doing work downstream. Retried jobs and duplicate deliveries then become no-ops.

Testing. The client almost certainly uses Guzzle or Symfony HttpClient. Mock at the HTTP layer — Http::fake() if it routes through Laravel's client, otherwise inject a Guzzle MockHandler. Do not try to boot the Symfony bundle in your test suite.

Gotchas and Tips

  • Container mismatch is the headline gotcha. The bundle registers services through Symfony\Component\DependencyInjection; Laravel's container never calls Bundle::build() or the extension's load(). Anything autowired inside the bundle (logger, serializer, HTTP client) will not resolve. Read the service YAML and translate the constructor arguments into your own provider.
  • Symfony's config schema is not Laravel config. Configuration.php is a TreeBuilder, not a publishable file. Don't try to "publish" it — recreate the relevant keys in config/monday.php.
  • 1.20 is an SF 8 compatibility bump, and that has a blast radius. The only change in this release is Symfony 8 support (PR #11). Practically: the tag likely raises the PHP floor (Symfony 8 targets PHP 8.4) and bumps symfony/* constraints. If you are on PHP 8.2/8.3, pin to the pre-1.20 tag rather than letting Composer downgrade your framework; if you're on 8.4, this release is your entry point. Either way, read composer.json at the tag — release notes won't tell you. There is no functional change to the Monday client itself, so no migration work and no behaviour change for existing users.
  • Version numbering is loose. The jump from 1.072 to 1.20 is not semver-sane; treat tag names as opaque labels and pin the exact version in composer.json. Don't rely on caret ranges to protect you here.
  • HTTP 200 with an errors array. Monday returns 200 for many failures (bad column ID, unknown board, permission denied). Your wrapper must check $response['errors'] and throw, or you get silent no-ops that surface days later as missing data.
  • Rate limits and complexity. 429 means back off; budgets reset per minute. Log the complexity block from each response and watch it. Batch mutations (create_items, change_multiple_column_values) in chunks of roughly 10–25.
  • Pin API-Version. Monday ships breaking changes quarterly. Whatever the bundle defaults to may be stale — and 1.20 did not touch it. Set it explicitly and bump deliberately.
  • Webhook challenge and signature. Echo the challenge byte-for-byte — do not re-encode the JSON with different whitespace. Verify the Authorization header against your signing secret and reject unsigned requests in middleware.
  • File uploads bypass GraphQL. Monday's file endpoint is multipart with the item ID in the form body; the bundle may not expose it. Plan for a raw HTTP call.
  • Package maturity. Zero stars, zero dependents, single maintainer. 1.20 is a one-line framework-compat release, which tells you the maintainer is tracking Symfony but not shipping features or docs. Treat it as a thin, readable wrapper: pin the exact version, expect to read its source rather than docs, and budget a day to audit the mutations it issues before depending on it.
  • Extend by decoration, not forking. If you do bridge the bundle, bind the bundle's client service in Laravel and layer your own query/mutation classes on top. Keep App\Services\Monday as the seam so replacing it with a hand-rolled client (or Saloon, which is idiomatic in Laravel) stays a one-day change.
  • Debugging. Log the raw query plus variables at debug level with the token redacted. Monday's error messages are terse; the query text usually tells you which variable was malformed.
  • Consider skipping the bundle. This release is a good argument for it: the only thing that changed was Symfony plumbing you don't use. For a Laravel app, roughly 200 lines of MondayClient over Laravel's HTTP client — query(), mutate(), retry(), throw() — often beats bridging a Symfony bundle. The bundle's real value is config schema and service wiring, and Laravel replaces both cheaply.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager