Product Decisions This Supports
Feature-level decisions
- Shipping graph-backed features in a PHP codebase. Any roadmap item that reads "related items," "recommendations," "fraud ring detection," "permission/entitlement graph," "data lineage," or "knowledge panel" typically resolves to a graph store; this package decides how the PHP application talks to it. It converts an infrastructure choice (Neo4j-compatible graph DB) into a code-level convention.
- Dynamic filter composition. The highest-value use case is user-driven filtering and search — catalog filters, faceted discovery, "find paths between X and Y." Hand-concatenated Cypher for dynamic filters is where injection bugs and unmaintainable string surgery live; a DSL makes query construction a data structure instead of string templating.
- Testability and reviewability of the data layer. Because queries become composable objects rather than string literals, they can be unit-tested, snapshotted, and reviewed in diffs. That's a quality-gate decision, not just a syntax preference.
Build vs. buy
- This is a small, boring, well-bounded component — a Cypher string builder, not a driver, not an OGM, not a migration tool. The genuine build cost is modest (weeks, not quarters), but it is pure undifferentiated work with a long tail of edge cases (nested patterns, variable-length paths,
MERGE semantics, parameter binding). Buying at MIT cost is rational if the abstraction fits.
- The real decision is three-layer separation: driver/connection (separate package), query construction (this package), and entity mapping (usually in-house). Adopting this package is a commitment to that middle layer only — keep it cheap and swappable.
- Do not treat adoption as an architecture commitment. The 19 stars / 0 dependents profile means this is a convenience, not a standard. Decide to adopt it the way you'd decide to vendor a utility library, not the way you'd decide to standardize on an ORM.
Roadmap and prioritization
- Lowers the cost estimate for graph features, which may move graph work up the roadmap — but only for read-heavy, ad-hoc query surfaces.
- Does not unlock bulk ingestion, graph algorithms (PageRank, community detection, shortest-path at scale), or streaming writes. Those belong to database-native tooling (
LOAD CSV, GDS/procedures, driver-level batching). Guard against a roadmap that assumes the DSL covers them.
- Opportunity score of ~31 / overall ~2.2 signals weak ecosystem pull. Treat this as an enabler for a feature you already want, never as a reason to want the feature.
Explicit non-decisions
- No managed service, no support contract, no SLA, no vendor relationship. The "cost" is MIT plus your own maintenance; the "risk" is unquantified because there is no user base to mine for failure reports.
When to Consider This Package
Adopt when most of the following hold
- The stack is PHP and will stay PHP for this service; the graph work lives in the same application or a PHP service, not a polyglot sidecar.
- The target database speaks Cypher / openCypher (Neo4j, Memgraph, FalkorDB, Neptune with openCypher, CognoDB-style engines). Verify dialect coverage against your engine — "Cypher" is not one language.
- Queries are constructed dynamically at runtime from user input, filters, or config. If 90% of your queries are static strings, the DSL earns little and costs a dependency.
- You want parameter binding by construction and a single place to enforce read/write query policy, timeouts, and logging — a chokepoint for governance.
- The team is new to Cypher. A fluent, discoverable builder lowers onboarding cost and reduces the "clever string" review burden.
- You can wrap it behind a thin internal interface (one or two dozen call sites) so replacement is a sprint, not a project.
- You are willing to pin an exact version and carry a fork if upstream stalls.
Look elsewhere when any of the following is true
- You need maturity signals. 19 stars, 0 dependents, and one maintainer org means no battle-testing, no Stack Overflow corpus, no third-party tutorials. For a revenue-critical path, that is a real (if bounded) risk. Pair it with a driver you trust (
laudis/neo4j-php-client or GraphAware's client) rather than expecting this package to cover connectivity, sessions, retries, or pooling.
- You need an ORM/OGM. Entity hydration, identity maps, relationship traversal, lazy loading — none of that is here. Look at a graph OGM or build a narrow repository layer.
- Performance is the product. If query shape is hand-tuned and hot-path, raw Cypher with a query plan review beats an abstraction that may emit suboptimal patterns. Also check whether the builder supports the planner hints and
PROFILE/EXPLAIN workflows you need.
- You need bulk writes, procedures, or algorithms. Use native tooling and
UNWIND-based batch patterns directly.
- The team is not PHP, or the graph access is being pushed to a service in another language.
- Procurement or audit requires vendor support. MIT gives you no recourse; if your policy requires a support path, this fails that screen regardless of technical merit.
- The builder's opinionated API fights your domain. If you find yourself string-escaping around the DSL regularly, the abstraction has negative value — abandon early.
Mitigations if you proceed: wrap it, pin it, contract-test the emitted Cypher against a real database instance in CI (not just string assertions), and record in an ADR that the cost of exit is under a sprint.
How to Pitch It (Stakeholders)
For executives (one paragraph)
We are evaluating a free, MIT-licensed PHP library that builds graph database queries in a structured, safe way instead of hand-written strings. It is a small utility — not a platform, not a vendor relationship — and the entire financial exposure is engineering time to adopt and, if needed, replace it. Its value is that it makes our graph-backed features cheaper to build, easier to test, and materially less exposed to query-injection and "mystery query" defects, because queries are assembled from typed, parameterized parts. Its risk is maturity: it is a low-adoption, single-maintainer project with no support contract, so we propose to use it behind our own internal interface, pin the version, and test the generated queries against a real database in CI. Worst case we fork or replace a few hundred lines. Recommended decision: approve for a scoped pilot on one graph feature, with a written exit plan — not as a standing architectural standard.
For engineering leads
- It solves one problem well: composing Cypher programmatically with parameter binding, instead of string interpolation. That is the class of bug that turns into an incident.
- It is not a driver, connection pool, session manager, retry layer, migration tool, or OGM. Budget those separately and pick a maintained driver.
- Integration is idiomatic Composer, PSR-friendly, no runtime services. Expect low friction; expect to read the source rather than the docs, because docs and community examples are thin.
- Mandatory guardrails: pin the exact version; hide it behind an internal query-builder facade; add integration tests that execute generated Cypher against a containerized database in CI; assert parameterization (no interpolated values) in a lint/test rule; document dialect assumptions if we are not on Neo4j.
- Verify before committing: openCypher coverage for the constructs we actually need — variable-length paths,
MERGE/ON CREATE/ON MATCH, subqueries and CALL {}, UNWIND, list/map literals, ordering and pagination, and any planner hints. Also confirm behavior on empty/invalid inputs, since we will be feeding it user-derived filters.
- Maintenance stance: assume we may own a fork. Keep our usage inside the documented common subset so a fork stays small, and avoid depending on incidental behaviors of the builder.
For the product owner
- Net effect: graph features get cheaper to build and easier to change, and the failure modes get less frightening.
- It buys nothing for ingestion pipelines, analytics-heavy graph algorithms, or reporting. Don't let "we have a Cypher builder" expand the scope of what we promise.
- Success looks like: one feature shipped, generated queries covered by tests, no hand-written Cypher outside the facade. If after that pilot the API is fighting us, we walk away cheaply — that is the intended design of this decision.