|
| 1 | +================= |
| 2 | +Local Development |
| 3 | +================= |
| 4 | + |
| 5 | +One of Gel's most powerful features is its seamless support for local development. The Gel CLI makes it incredibly easy to spin up a local instance, manage it, access GUI, and iterate on your schema quickly and safely. This guide outlines the flexible options available for your local development workflow. |
| 6 | + |
| 7 | +If you're using JavaScript or Python, our client libraries will automatically handle the installation for you using tools like ``npx`` and ``uvx``. For other environments or to install the CLI globally, you can use one of the following methods: |
| 8 | + |
| 9 | +.. include:: ./install_table.rst |
| 10 | + |
| 11 | + |
| 12 | +Initialize your local instance |
| 13 | +============================== |
| 14 | + |
| 15 | +It's easy to get started with a local Gel instance. Navigate to the root of your project repository and run: |
| 16 | + |
| 17 | +.. code-block:: bash |
| 18 | +
|
| 19 | + $ gel init |
| 20 | +
|
| 21 | +This command takes care of several things for you: |
| 22 | + |
| 23 | +* It downloads and installs the latest version of the Gel server. |
| 24 | +* It configures a local Postgres cluster. |
| 25 | +* It manages the instance through your operating system's background task launcher. |
| 26 | + |
| 27 | +To conserve resources, Gel automatically puts inactive local development instances to sleep. This means you can have multiple instances running without them draining your system's resources when not in use. |
| 28 | + |
| 29 | +Iterate on your schema |
| 30 | +====================== |
| 31 | + |
| 32 | +Gel simplifies the process of evolving your data model. You can apply changes from your Gel schema files directly to your running local instance without needing to create a separate migration file for every minor adjustment. |
| 33 | + |
| 34 | +There are two primary ways to apply schema changes during development: |
| 35 | + |
| 36 | +1. **Automatic updates with** :gelcmd:`watch --migrate` |
| 37 | + For a hands-off approach, you can use the watch command. This starts a process that monitors your Gel schema files for changes and automatically migrates your local instance as soon as you save them: |
| 38 | + |
| 39 | + .. code-block:: bash |
| 40 | +
|
| 41 | + $ gel watch --migrate |
| 42 | +
|
| 43 | + This is ideal for rapid iteration when you want to see your schema changes reflected immediately. |
| 44 | + |
| 45 | +2. **Manual updates with** :gelcmd:`migrate --dev-mode` |
| 46 | + If you prefer more explicit control, or don't want a background process running, you can apply schema changes manually: |
| 47 | + |
| 48 | + .. code-block:: bash |
| 49 | +
|
| 50 | + $ gel migrate --dev-mode |
| 51 | +
|
| 52 | + This command performs the same action as the watch --migrate mode—applying the current state of your schema files to the local instance—but only when you explicitly run it. |
| 53 | + |
| 54 | +Finalizing changes |
| 55 | +================== |
| 56 | + |
| 57 | +Once you're satisfied with the schema changes you've made iteratively, you'll want to create a migration file which will be committed to version control and shared with others. This new migration file will encapsulate all the modifications made since your last migration. |
| 58 | + |
| 59 | +1. **Create the migration file** |
| 60 | + .. code-block:: bash |
| 61 | +
|
| 62 | + $ gel migration create |
| 63 | +
|
| 64 | + This command inspects the differences between your last migration file and the current state of your database schema, then generates a new migration file reflecting these changes. |
| 65 | + |
| 66 | +1. **Align your local instance** |
| 67 | + After creating the migration, run the following command to ensure your local instance's migration history is aligned with this new migration. You can do this by running: |
| 68 | + |
| 69 | + .. code-block:: bash |
| 70 | +
|
| 71 | + $ gel migrate --dev-mode |
| 72 | +
|
| 73 | + This command effectively "fast-forwards" your local instance. From its perspective, it will appear as though all the iterative changes were applied as part of this single, new migration. This keeps your local development environment consistent with the migration history you'll use in other environments (like staging or production). |
| 74 | + |
| 75 | +Undoing destructive changes |
| 76 | +=========================== |
| 77 | + |
| 78 | +Mistakes happen! You might accidentally make a destructive schema change. Fortunately, Gel has your back. Every time you migrate your schema (either via :gelcmd:`watch --migrate` or :gelcmd:`migrate --dev-mode`), a backup of your local instance is automatically taken. |
| 79 | + |
| 80 | +If you need to roll back to a previous state: |
| 81 | + |
| 82 | +1. **Stop any active migration processes**: Ensure :gelcmd:`watch --migrate` is not running. |
| 83 | + |
| 84 | +2. **Find the backup ID**: Look through your shell's scrollback history. You'll find messages indicating backups were made, along with their IDs. Identify the ID of the backup created before the destructive change. You can also use the :gelcmd:`instance listbackups` command to list all backups for this instance. |
| 85 | + |
| 86 | +3. **Restore the instance** |
| 87 | + .. code-block:: bash |
| 88 | +
|
| 89 | + $ gel instance restore <backup-id> -I <your-local-instance-name> |
| 90 | +
|
| 91 | + Replace <backup-id> with the actual ID and <your-local-instance-name> with the name of your instance (e.g., my_project). This will restore both your data and schema to the state at that backup point. |
| 92 | + |
| 93 | +Once restored, you can make the intended schema changes and then restart :gelcmd:`watch --migrate` or use :gelcmd:`migrate --dev-mode` as preferred. |
| 94 | + |
| 95 | +Keeping code in sync |
| 96 | +==================== |
| 97 | + |
| 98 | +Many Gel language bindings offer code generation capabilities (e.g., query builders, typed query functions). This generated code needs to stay synchronized with your schema. Gel provides a system of hooks and watchers that you can configure in your |gel.toml| file to automate this. |
| 99 | + |
| 100 | +These hooks can trigger codegen scripts when: |
| 101 | + |
| 102 | +* The schema changes (using the "schema.change.after" hook). |
| 103 | +* Specific files are edited (using watch scripts). |
| 104 | + |
| 105 | +Here's an example |gel.toml| configuration for a TypeScript project. It runs a query builder generator and a queries generator at the appropriate times: |
| 106 | + |
| 107 | +.. code-block:: toml |
| 108 | +
|
| 109 | + [instance] |
| 110 | + server-version = "6.7" |
| 111 | +
|
| 112 | + [hooks] |
| 113 | + "schema.change.after" = "npx @gel/generate edgeql-js && npx @gel/generate queries" |
| 114 | +
|
| 115 | + [watch] |
| 116 | + "src/queries/**/*.edgeql" = "npx @gel/generate queries" |
| 117 | +
|
| 118 | +Explanation: |
| 119 | + |
| 120 | +* ``[hooks] / "schema.change.after"``: When any schema change is successfully applied, we run the query builder generator (to reflect schema structure changes) and the queries generator (to update based on new or modified types). |
| 121 | +* ``[watch] / "src/queries/**/*.edgeql"``: If any ``.edgeql`` files within the ``src/queries/`` directory (or its subdirectories) are modified, the command ``npx @gel/generate queries`` is executed. This ensures that your typed query functions are always up-to-date with your EdgeQL query definitions. |
| 122 | + |
| 123 | +By configuring these hooks and watchers, you can maintain a smooth workflow where your generated code automatically adapts to changes in your schema and query files. |
0 commit comments