Skip to content
This page View Markdown Open in ChatGPT Open in Claude

Git integration

Everything you build in API Maker is text : schemas, custom APIs, hooks, events, schedulers, settings, groups, test cases… API Maker keeps it in a Git repository of yours, branch by branch, and pulls it back on any other server.

Set up Connect a repository on the Git page, or Profile → User info : the Git URL with credentials, and the email of the commit user.
Branch Branches on the Git page : a click makes a branch the working branch, the one commits go to and pulls come from. New branch from another one ; delete one from its row.
Pull Replaces the code of the account with the branch, then runs the migration scripts not yet executed here.
Push Shows the status, lets you compare and revert, then commits with your message. Pull requests are raised in your Git host.
Never in Git Secrets.
From a branch to live : pull request, pull, one transaction, migration scripts 1 · branch Commit and push from the panel, or from your editor 2 · review Pull request on your Git host ; secrets are not in it 3 · pull On the environment the Pull button, or a deployment hook of CI 4 · all or none One transaction every item of the branch replaces its own 5 · migrations Then live the scripts not run here yet, in order a stage with errors : rolled back, nothing changes DEV, QA, UAT and PROD each pull the same branch, with their own secrets and data.

What goes to Git

  • One folder per kind in src, one folder per item in it, the item as YAML and its code in a file of its language : .ts for TypeScript, .py for Python, .php, .cs for C#, .go, .rs for Rust, .java, .kt for Kotlin.
  • Settings are always a .ts file, whatever language the code is written in : the Basic Info of a custom API, the settings of the APIs of a table and of a system API and a schema (<name>.config.ts), the texts of internationalization and what a token generator is (<name>.ts). See settings are always TypeScript.
  • The sandboxes of the account : src/admin_user/data.yaml holds the runtimes, versions, packages and variables of each language, and the Dockerfile written for a language is src/admin_user/sandbox/<language>/Dockerfile.
  • Secrets never leave the server. Each environment keeps its own, which is the point : the same code runs against another database because the secret differs.
  • The folder is what the local client syncs to your disk, so the same files open in your editor.
  • AGENTS.md at the root is the guide of API Maker for AI agents (Codex, Claude Code, Cursor, Copilot) : where everything is, how code is written, the rules of security and how to fix the findings of the security report. Every commit writes its block again ; what you write around the block stays. See AGENTS.md in your repository.
A repository with a custom API in TypeScript, one in Go and a scheduler in Python
AGENTS.md                            the guide for AI agents
package.json  tsconfig.json          TypeScript
go.mod  am/am.go  am/methods.go      Go : the module "apimaker" and the package your code imports
pyproject.toml                       Python
src/
  custom_apis/
    orders/
      orders.yaml                    the item : name, versions, hooks (no code)
      orders.ts                      its code
      orders.config.ts               its settings (path, method, access) : TypeScript in every language
      pre-hooks/check_stock.ts       a hook before it
    stock/
      stock.yaml
      stock.go                       package of its own : src/custom_apis/stock
      stock.config.ts
      pre-hooks/audit/audit.go       a hook of Go is a package of its own too
  schedulers/
    Daily_report/
      Daily_report.yaml              name: Daily report
      Daily_report.py
  collection_hooks/
    Row_scope-customers/
      Row_scope-customers.yaml       the hook : its table, before or after the APIs, its place there (no code)
      Row_scope-customers.ts         its code
    Check_access/
    Check_access--orders/            a second hook named "Check access" : its table tells it apart
  schemas/  instances/  events/  web_socket_events/  utility_classes/  test_cases/  …
  admin_user/data.yaml

The names of the folders

What Its folder Example
A kind Its name in small letters, _ for a space custom_apis, schemas, instances, instance_api_settings, instance_api_hooks, instance_hooks, database_hooks, collection_hooks, system_api_settings, system_api_hooks, events, web_socket_events, schedulers, process_initializers, database_migrations, utility_classes, test_cases, auth_providers, i18ns, groups, api_users, log_profiles, api_testing_states, api_security_report, auto_increments, admin_user
An item, and the files in it Its name ; what is no letter, digit, ., - or _ is written _ The scheduler Daily report is src/schedulers/Daily_report/Daily_report.py
A hook of an instance, a database, a table, an API of a table, a system API A folder of its own, named by the hook src/collection_hooks/Row_scope-customers/Row_scope-customers.ts, see Hooks
A hook of a custom API, a version, a listener The same rule, in the folder of the item pre-hooks/check_stock.ts, versions/2/Faster.ts, listeners/send_a_mail/send_a_mail.py
  • No folder has a space in its name : the tools of every language take the repository as it is (a folder is a package in Go, and its name is part of what code imports).
  • The name itself is in the YAML of the item (name: Daily report). Nothing is read back from the name of a folder, so two names are never mixed up by it.
  • Renaming an item shows as its files deleted and added under the new name.

Hooks

The hooks of an instance, a database, a table, an API of a table and a system API are a folder each, named by the name you gave the hook : instance_hooks/, database_hooks/, collection_hooks/, instance_api_hooks/, system_api_hooks/. The folder holds the code of the hook in its language and its YAML.

src/collection_hooks/Row_scope-customers/Row_scope-customers.yaml
_id: 6a39057e8e907bb90f6971e7        # the hook
active: true
collectionName: customers            # where it runs : instanceName, databaseName, collectionName, apiId
databaseName: shop
groupNames: [shop_app]
guid: 01M5RRJ7P2SVB20TX2QA4HE78R     # the hooks of the table are kept together under this guid
hookType: pre                        # pre : before the APIs, post : after them
instanceName: mongodb
isActive: true
name: Row scope - customers
order: 1                             # its place among the pre hooks of the table
  • Two hooks of one name. The oldest keeps the name, the next one gets what tells it apart, then a number : Check_access, Check_access--orders (its table), Check_access--orders--2. A hook of a database is told apart by its database, of an instance by its instance, of an API by its table and its API (Check_access--orders--GEN_GET_ALL), of a system API by the API (Check_access--GET_TOKEN). Names are compared without case, as the disk of Windows or macOS does. A hook which is added never takes the folder of another one.
  • The order of the hooks of a list is order : change it there, or with the arrows of the list in API Testing.
  • On your disk. Write a folder with its YAML and its code, and the local client adds the hook to its table, at its order ; a YAML without _id is a new hook. Delete the folder of a hook and the hook goes ; a table, a database, an instance or an API whose last hook goes has no row of hooks left. Rename a hook in its YAML and the local client gets every file again : its folder moved.
  • A table (or any place) without hooks has no folder.

A project of every language

Besides package.json and tsconfig.json, a commit writes the file each language you use needs, with the packages of its environment in Sandbox settings as its dependencies, and what your code imports of API Maker as source. Open the repository in your editor and the code resolves, completes and compiles as it does in a sandbox.

Language Written at the root Check it yourself
TypeScript package.json, tsconfig.json, am-types/ npx tsc --noEmit
Python pyproject.toml python -m compileall src
PHP composer.json composer validate, php -l <file>
Go go.mod, am/am.go, am/methods.go go build ./..., go vet ./...
Rust Cargo.toml, am/rust/ (the crate am, and project.rs which names every .rs file as a module) cargo check
C# ApiMaker.csproj, am/dotnet/ dotnet build
Java settings.gradle.kts, am/java/build.gradle.kts, am/jvm/am/ (what the code imports of API Maker : G, Json, AmErrors…) gradle check
Kotlin settings.gradle.kts, am/kotlin/build.gradle.kts, am/jvm/am/ gradle check
  • Go : a package per folder. Each piece of Go code is alone in its folder. Where a folder would hold two (the hooks of a list, the functions of a token generator), each is in a folder named as its file : pre-hooks/audit/audit.go, users_tg/users_tg.tg/users_tg.tg.go. The code a new item starts with says package code ; the sandbox builds it as a plugin whatever its package is named. A file is never named as Go reads names : orders_test is written orders_test_.go.
  • C# : file static class Api. A class marked file is known in its file only, so every file can have its own Api and they still compile as one project. The code a new item starts with is written that way.
  • Rust needs no care : every file is a module of the library am/rust/project.rs lists.
  • Java and Kotlin : a folder per piece of code, a build of Gradle. The files of a folder are compiled together, and every piece of code has its main (in Java, its class Api too). So a file which is not the only code of its folder is in a folder named as the file, as in Go : pre-hooks/check/check.java, users_tg/users_tg.tg/users_tg.tg.kt. Each folder of code is a source set of its own in the project of its language, compiled on its own with the utility classes, as a sandbox compiles it. settings.gradle.kts finds the projects there are : an account with code in both languages has both, and one am/jvm/am/. When the settings name a version of the JDK, the Java project compiles for it (options.release); the Kotlin project uses the plugin of Kotlin 2.4.20, the compiler of the sandboxes.
  • Utility classes resolve as in a sandbox. A utility class is src/utility_classes/<folder>---<name>/<name>.<extension> (utils---Tax/Tax.py for the class Tax of the folder utils/), and the file of the project of its language makes the code find it by the name it imports :

    Language What the commit writes for the classes The code
    TypeScript tsconfig.json : a path utils/Tax for each class import * as tax from 'utils/Tax';
    Python pyproject.toml : the folders of the classes for Pyright / Pylance, pytest and mypy from Tax import add
    PHP composer.json : the files of the classes under autoload.files Tax::add(100)
    Rust am/rust/project.rs : pub mod Tax; with the path of its file use crate::Tax::add;
    Go nothing : the folder is the package import tax "apimaker/src/utility_classes/utils---Tax"
    C# nothing : one project compiles every file Tax.Add(100)
    Java, Kotlin nothing : the project of Gradle compiles the folders of the classes together (the source set utilities), and every piece of code with them Tax.add(100)
    - .gitignore gets what those tools build : /target/, /bin/, /obj/, /vendor/, /.venv/, __pycache__/, /.gradle/, /.kotlin/, /build/, /am/*/build/.

Repositories written before

  • A repository written by an earlier version has the kinds as they are named (src/Custom APIs, src/Utility classes) and the items by their names with spaces, and may keep code of every language in .ts files. It is pulled as it is.
  • The next commit moves each kind you commit to its folder of today and removes the old one : the status lists the files as deleted and added once. The history of an item goes on across the move.
  • Take the localClient.js of that commit : the local client of before does not know the new folders.
  • Hooks in the folder of their row. A branch written before the hooks had a folder each has the hooks of a table (an instance, a database, an API) in one folder, named by its guid or by its place (src/collection_hooks/01M5RRJ7P2SVB20TX2QA4HE78R/pre-hooks/Row_scope-customers.ts, src/Collection hooks/mongodb -- shop -- customers/…). It is pulled as it is. The status shows a hook which only moved to its own folder as no change, and a hook which changed since as modified, compared with what it was ; the next commit moves them all.
  • A file of code made on your disk names its language by its extension : orders.py in a new folder of custom_apis is a custom API in Python. A file of settings is read as .ts only : orders.config.py is not the settings of orders.

Repositories and databases of API Maker 3

  • A branch API Maker 3 wrote (src/Custom APIs…) is pulled as it is. The next commit writes it the way API Maker 4 does (src/custom_apis…).
  • Hooks of API Maker 3 (src/Collection hooks/<guid>/pre-hooks/<name>.ts, src/Instance API hooks/…, src/System API hooks/<API>/…) are pulled with their code, their ids, their lists and their order ; a row of hooks without a hook (API Maker 3 kept many) is pulled too, and the next commit writes no folder for it. The next commit gives every hook a folder of its own.
  • UI Maker and third party APIs are not pulled : API Maker 4 has neither. The folders DB masters, DB master utils, UI maker styles, Third party APIs, Third party API settings, and the WebSocket events of third party APIs, stay in the branch and nothing of them is saved. The pull panel lists them once the pull is over, and so does the log of the pull. The next commit removes them from the branch.
  • Every sandbox of API Maker 3 had npm packages of its own (lodash, moment, crypto-js…), which code could require without listing them. The ones the code of the branch takes become packages of the account, at the version API Maker 3 had. Code marked Run on native process finds the packages installed in the folder of the server instead : the log of the pull names the ones to install there (npm install [email protected]).
  • A third party API installed from the store of API Maker 3 brought npm packages into the sandboxes of the account (@aws-sdk/client-s3 of aws-s3-bucket), and its utility classes are in the branch (utils/aws-s3-bucket/1.0.0/S3BucketUtility). The utility classes are pulled with the others, and the packages of the third party API which the code takes become packages of the account, at the version the API had.
  • The enums of UI Maker which code of API Maker 3 reads (EDBMasterFormControl.file_upload in the uim of a schema property) are still there for that code : such a schema saves as it did.
  • Two items of a part which give one guid (a folder copied by hand : API Maker 3 could not pull such a branch either) are both pulled : the first keeps the guid, the next one gets its own, the same at every pull. The pull panel and the log of the pull name it, and the next commit writes it to the branch.
  • The Dockerfile of an API Maker 3 account (src/Admin user/Dockerfile) builds no sandbox in API Maker 4, and the next commit leaves it out. The sandboxes of API Maker 3 ran Alpine, those of API Maker 4 run Debian : a program of the system the code calls (ping…) goes in the Dockerfile of the JavaScript environment (apt-get install -y iputils-ping).
  • A server of API Maker 4 started on the database of an API Maker 3 installation does the same once, for every account : the packages its code takes are listed (those of its third party APIs too), and a WebSocket event whose code is in its versions only gets that code as the code which says who may connect. A pull of API Maker 3 left that code empty, so API Maker 3 never ran it. A database API Maker 3 never ran on is left as it is.

Pull

  1. Make the branch the working branch, click Pull. The panel shows the Steps on the server and a live log.
  2. The items of the branch replace the ones of the account. The tag last pulled of a branch, and the line under the working branch, show what the account runs, also when a deployment hook or another browser pulled it.
  3. The active migration scripts which never ran on this environment are listed : run them, in order.

  4. Pull without secret (in the menu of the Pull button) : for a repository made on another installation, whose passDBEncryptDecrypt differs. The passwords of the API users can not be decrypted, so they are set to read their password from the secret (common.apiUserPasswords.default). Add those passwords to your secret.

Push

  1. Check status lists every file which differs from the branch : added, modified, deleted. Filter the list, expand all.
  2. Compare opens one file in the compare editor ; View all changes in one diff shows them together.
  3. Tick the changes to commit. A new status ticks every change except those of Auto Increments, which belong to one environment. The checkbox of a kind of item, of an item, or of the filter bar (every listed change) ticks all of its files ; a filter hides changes without unticking them. The line above the message says what the commit carries : Commits 9 of 10 changes · Schemas 3 · API users 1 ….
  4. Revert puts a file back to the branch, in the account too ; Revert N selected puts back the ticked changes. Some files can not be reverted from here : the files written for the editors (types/db-interfaces.d.ts, the project files), AGENTS.md, the API Security Report and Auto Increments. They stay ticked.
  5. Write the message and Commit to the working branch : the ticked changes are committed and pushed. The others stay out of the commit, and the next status still lists them.

  6. Renaming a hook moves its folder : its two files show as deleted and added under the new name.

The history of one item

  • The Git icon in the header of an item (a custom API in API Testing, a schema, a scheduler, an event, a group…) opens its History : the version live in the database, then every commit of the working branch which changed the item, with its author and date. Load older versions reads further back.
  • Changes compares the selected version with the Previous one, the Database, or a version pinned in the list ; Full version shows it whole. Each file of the item is a tab.
  • Revert writes the selected version into the database only : the database version shows UNCOMMITTED until it is committed.
  • A hook (the Git icon of a hook in API Testing, or of the form of a hook) has the history of its folder, and before it had one, of its file in the folder of its row. Its revert takes back that hook only, the other hooks of its table stay as they are. The history of the hooks of an API (the icon of the API) has the folders of all of them.

Deployment hooks

  • A deployment hook is an URL of your server which pulls a branch, for a CI pipeline or the webhook of your Git host. Create it in the Git panel : a name, an access token and a secret, and the IPs allowed to call it. The name and the access token take letters, digits and _ only ; the secret takes any character.
GET /api/sites/deploy/<user path>/<hook name>?token=<access token>&secret=<secret>&branch=main
  • syncMode=SYNC_WITHOUT_SECRET pulls like the Pull Without Secret button ; runMigrationScripts=false skips the migration scripts.
  • The last callers are kept, so the panel can show where the deployments came from.