Repository navigation
Conversation
…3 names
The v3 metadata API did not just rename v2's vocabulary, it redesigned the
payload: the table type became a Jackson discriminator on `schema`, direction /
indexes / groups / caches moved inside `schema`, a multi-edge id was hoisted out
of `_id` and a vertex id out of `src`, type values became lowercase, and the v2
response envelopes were dropped. A v2 payload therefore could not be carried to
v3 by renaming keys, which left every ecosystem client (the Go CLI, the ops
scripts, the console form, the DDL fixtures) maintaining two shapes.
Make the surface v2's structure with v3's names, so the two dialects differ by
key names alone:
desc -> comment dirType -> direction
schema.src -> schema.source indices -> indexes
schema.tgt -> schema.target .name -> .index / .field
schema.fields -> schema.properties
INDEXED -> EDGE IMMUTABLE_INDEXED -> IMMUTABLE_EDGE
mode IGNORE -> mode DROP name "a.b" -> database + table
Type values stay uppercase because the surface now carries v2's own `DataType`
and `VertexType`; `DECIMAL` no longer collapses into `OBJECT` on the way through.
A multi-edge keeps its id as the `_id` property and a vertex keeps its id in
`source`, exactly as v2 stores them. Listings return `{count, content}` and
mutations `{status, result, message}`, the same envelopes v2 serves. The v2-only
`event` and `readOnly` flags leave the surface; the server derives them.
`V3MetadataConverter` is now a pure rename in both directions -- all the schema
reshaping is gone. The engine is untouched: `ModelSchema`, `V3TableDescriptor`,
`V2BackedTableBinding`, `PrimitiveType` and the `/graph/v3/.../edges` data plane
are exactly as they were, and `/graph/v2` keeps serving its own dialect.
The immutable-edge invariants (at most one index, never BOTH) lived in
`ModelSchema.ImmutableEdge.init`, which the surface no longer builds, so they
move to `TableCreateRequest` -- otherwise creation would succeed and the table
would fail later, when the runtime projects it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`TableDescriptor`, `DatabaseDescriptor` and `AliasDescriptor` were only ever the v3 API's response types -- the engine reads `ModelSchema` and projects it through `v2.engine.v3.V3TableDescriptor`, never these. With the surface serving its own flat responses, nothing constructs them, and the `Id` hierarchy and `payload/Database*Request` under them have no callers either. `V2ServiceDescriptor.toV3` and `V2AliasDescriptor.toV3` converted to two of the removed types. Both live in `core.v2.metadata`, a parallel v2 model whose only callers are its own serialization tests, so they go with them. `Id` stays: those same `core.v2.metadata` identifiers still implement it. No behavior changes -- nothing reachable from an endpoint referenced any of this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rewrite the metadata API reference against the flat surface: the data model, the
request and response examples, the envelopes, and a field-by-field v2 mapping
table in place of the old three-row terminology list.
Two rules in the reference were already wrong and are corrected here: the name
pattern is `^[a-z][a-z0-9_]{0,63}$`, not the mixed-case form, and the storage URI
allows an empty namespace.
The glossary and schema pages carried the mapping as "v2 (Current) -> v3
(Future)". The mapping is now what the API actually serves, so say so.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Closing this for now to give it some more thought. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/graph/v3/.../metadatais already a façade over the v2 DDL services — there is no v3 metastore behind it. But the façade did not only rename v2's vocabulary, it redesigned the payload: the table kind became a Jackson discriminator onschema, direction/indexes/groups/caches moved insideschema, a multi-edge id was hoisted out of_idand a vertex id out ofsrc, type values became lowercase, and the v2 response envelopes were dropped.The consequence is that a v2 payload cannot be carried to v3 by renaming keys. Everything downstream that speaks metadata — the Go CLI's hand-written structs, the ops scripts' raw JSON parsers, the console's table form, the DDL fixtures — has to know two shapes and translate between them. That cost buys nothing: the two describe the same stored entity.
This makes the v3 surface v2's structure with v3's names, so the dialects differ by key names alone.
Type values stay uppercase because the surface now carries v2's own
DataTypeandVertexTyperather than mapping throughPrimitiveType. That also stopsDECIMALcollapsing intoOBJECTon the way through, which the old converter did in one direction and could not undo in the other.A multi-edge keeps its id as the
_idproperty and a vertex keeps its id insource, exactly as v2 stores them. Hoisting them read better, but it is what made the two shapes non-mechanical to convert, which is the thing being fixed. Listings answer{count, content}and mutations{status, result, message}— the sameDdlPageandDdlStatusv2 serves. The v2-onlyeventandreadOnlyflags leave the surface; the server derives them, as it already did.V3MetadataConverteris now a rename in both directions and nothing else — the schema reshaping, the_idlifting, the vertex target synthesis and the four-wayModelSchemadispatch are all gone.The engine is untouched.
ModelSchema,v2.engine.v3.V3TableDescriptor,V2BackedTableBinding,PrimitiveTypeand the/graph/v3/.../edgesdata plane are exactly as they were, and/graph/v2keeps serving its own dialect for backward compatibility.tools/v3v2-boundary-checkreports the same boundary as before: the v2 dependency stays confined to the three metadata controllers plus the datastore-references path.Two things worth a reviewer's attention.
The immutable-edge invariants — at most one index, never
BOTH— lived inModelSchema.ImmutableEdge.init. The surface no longer builds aModelSchema, and the v2 metastore does not know about immutable edges, so those checks move toTableCreateRequest. Without the move, creation would have succeeded and the table would have failed later, when the runtime projects it.DELETEnow answers{"status": "DELETED", ...}with 200 rather than 204, which is the envelope decision applied consistently. A table'stypeanddirectionare not updatable, matching what the previous surface allowed.Changes
server/api/graph/v3/metadata/): newTableType,TableSchema,TableResponse,DatabaseResponse,AliasResponseandDdlEnvelopes;TableCreateRequest/TableUpdateRequest/Database*Requestrewritten flat; the three controllers andV3CompatServicerewired ontoDdlPage/DdlStatus.V3MetadataConverterreduced to renames —LabelEntity <-> TableResponse,ServiceEntity <-> DatabaseResponse,AliasEntity <-> AliasResponse, plusLabelType <-> TableType.QueueMetadataServicebuilds its backing table through the new request type.TableDescriptor,DatabaseDescriptor,AliasDescriptor, theIdhierarchy under them andmetadata/payload/are removed — they were only ever this API's response types and nothing constructs them now.Iditself stays, sincecore.v2.metadataidentifiers still implement it.V2ServiceDescriptor.toV3andV2AliasDescriptor.toV3went with the types they converted to.^[a-z][a-z0-9_]{0,63}$, and the storage URI allows an empty namespace. The glossary and schema pages carried the mapping as "v2 (Current) -> v3 (Future)"; it is now what the API serves.How to Test
./gradlew :server:test --tests '*V2V3CompatibilityTest*'— the contract. Every case writes through one dialect and reads back through the other, acrossEDGE/IMMUTABLE_EDGE/MULTI_EDGE/VERTEX, in both directions, covering the whole rename table includingindices/indexes,IGNORE/DROPand the derivedreadOnly../gradlew :server:test --tests '*api.graph.v3.metadata.*'— CRUD, status filtering, name validation and cache round-trips on the new shape../gradlew :server:test --tests '*ImmutableEdgeE2ETest*' --tests '*VertexIntegrationTest*'— the immutable-edge invariants still answer 400, and a vertex table still works with its id insource../gradlew :server:test --tests '*v2*' --tests '*Ddl*'— v2 backward compatibility, unchanged../gradlew :tools:v3v2-boundary-check:run— the v3-to-v2 boundary is the same as before../gradlew spotlessCheck build— formatting and the full build (746 tests).AI Assistance