Recipes
Step-by-step changes for the server. Each ends with how to check it worked. Run commands from the repo root of grandstack-server. These are written so a developer or a coding agent can follow them literally.
Where to run this. Commands on this page that start with
npm,nodeordocker buildrun inside a clone of this repository:git clone https://github.com/grand-stack/grandstack-server, thencd grandstack-server(Node 22 or later; runnpm cionce). Commands that need the running stack use thegrandstackrepository’s compose files: see the quickstart.
Add a field to an existing type
Example: add country: String to Movie.
- Edit
schema/schema.graphql: add the field with a description."""Country of production.""" country: String - Run
npm run lint(fails if you forgot the description) andnpm run schema:check(adding a field is not breaking).schema:checkcompares with the schema committed at gitHEAD, so it needs a git checkout and only means something if you committed the baseline before editing; outside git it stops with a message saying so. - Run
npm run docs:schemato refresh the reference, and commit it. (npm run docs:checkfails until you have run this.) - If the field should be in the sample data, bump
// seed-versionand add statements toseed/movies.cypher. The bundled file was produced by a one-off script that is not shipped in the repo, so edit the file directly: to set a property on a few existing films add a line likeMATCH (m:Movie {title: "The Matrix"}) SET m.country = "USA";before the final derived-counts statement (the file already does this forPerson.born). - Restart the server:
docker compose up --build serverin thegrandstackrepo (the schema is copied into the image), or, without a rebuild, mount your schema file as shown in configuration. A bumped seed only reloads on a database that has the seed marker; withSEED=falseyou must write the data yourself. Check:curl -s localhost:4000/graphql -H 'content-type: application/json' -d '{"query":"{ movies(limit:1){ title country } }"}'. - The web app needs
npm run codegento see the field (seedocs/recipes.mdin thegrandstack-webrepo).
Add a relationship
Example: Movie has a Studio.
- Add
type Studio @node { """Studio name.""" name: String! movies: [Movie!]! @relationship(type: "PRODUCED", direction: OUT) }. - On
Movieaddstudio: Studio @relationship(type: "PRODUCED", direction: IN). Use[Studio!]!for many. - Add the unique constraint and the
MERGEstatements to the seed; bump the seed version. - Lint,
schema:check,docs:schema, restart. - Check with a query for
movies { title studio { name } }.
Add a computed field
Use @cypher (schema guide). Remember columnName, arguments as $name, and that you cannot sort or filter by it. If you need to sort or filter, store the value as a property and refresh it (see how the film counts work in seeding).
Change the sample data
- Edit the seed (it is generated data; if you have the generator, change that).
- Bump
// seed-version: N. - Restart. A database seeded by this server reloads; check the log for
Loaded seed.
Add types without touching the base schema
Put them in a new file and load it with SCHEMA_EXTRA_PATHS=/app/schema/extra.graphql (mount the file into the image). Use extend type Movie { ... } to add fields to existing types. For constraints and indexes the new types need, write idempotent Cypher (CREATE CONSTRAINT ... IF NOT EXISTS) in a file listed in SETUP_CYPHER_PATHS. This is how grandstack-auth adds users, reviews and its access rules.
Add a server plugin
Plugins wrap execution. src/refreshCountsPlugin.ts is a complete example: it uses onExecute with setExecuteFn to run code after a mutation. Add yours to the plugins array in src/index.ts, and write unit tests with fakes like test/refreshCountsPlugin.test.ts.
Turn on an environment option
Add the variable to Config and loadConfig in src/config.ts with a default, validate it, add a test in test/config.test.ts, use it in src/index.ts, then add it to the table in configuration and to AGENTS.md.
Before you commit
npm run lint && npm test && npm run schema:check && npm run docs:check
Source: grandstack-server/docs/recipes.md (this page is a copy; edit it in the repository)