Skip to content

CoreAPI Development Guide

This guide covers the general workflows and what's needed for you to develop the CoreAPI backend.

Develop the backend and redeploy it with microservices

  • Develop the code in your dedicated domain or package (e.g. domain/commerce, domain/identity).
  • Use the corresponding make commands in the Quickstart directory to run your backend and the required microservices it depends on (Postgres, Redis, NATS, AuthAPI, Zitadel, etc.).
  • CoreAPI itself is orchestrated via compose/services/CoreAPI.yml — you generally won't need to touch this unless you're changing how CoreAPI itself is built/run, not just the code inside it.
  • Each make target maps to a specific combination of infra + services (see the Makefile at the root of Quickstart). Pick the target that matches what you're actually working on rather than always reaching for make base or make reset-all — this keeps rebuild times down and avoids spinning up services you don't need.

Example — working on a CoreAPI + Spatio (Malaysia ticketing) change:

Say you're editing something in domain/commerce and want to see it running against the Malaysia/ticketing stack (CoreAPI + SpatioAdmin + TicketCMS):

# 1. Make your code change in CoreAPI
#    e.g. edit domain/commerce/services/payment_service.go

# 2. From the Quickstart directory, bring up the matching stack
make malaysia
#    this runs: $(INFRA) $(COREAPI) $(SPATIO) up --build -d
#    → Postgres/Redis/Zitadel infra, CoreAPI (rebuilt from your change),
#      SpatioAdmin, and TicketCMS

# 3. Test your change
curl -i http://localhost:3000/api/orderTicketGroup?id=test123
#    or open SpatioAdmin/TicketCMS in the browser and exercise it manually

# 4. Tear it down when you're done
make malaysia-down       # stop containers, keep volumes/data
make malaysia-down-v     # stop containers AND wipe volumes (fresh DB next time)

The --build flag means make malaysia always rebuilds the CoreAPI image from your current code before starting — you don't need a separate build step. If you only changed CoreAPI code (not docker-compose/Dockerfile config), this is usually all you need between edits: just re-run make malaysia again.

Adding or configuring a microservice

  • In the Quickstart folder, YAML files are already separated by concern for local development — compose/infrastructure/ for shared infra (Postgres, Redis, NATS, Zitadel, SeaweedFS, CDN stack, etc.) and compose/services/ for the actual PlayTelly/CoreAPI-adjacent services (CoreAPI, PlayoutAdmin, TicketCMS, OrgConsole, etc.). Each is written the way you'd expect a normal docker-compose file to look.
  • If you ever need a new microservice, add its YAML under the appropriate compose/infrastructure/ or compose/services/ folder, then map it into the root Makefile so it's included in the relevant make target.
  • Full detail on how the microservice orchestration itself works (compose file structure, networks/volumes, service dependencies) is covered in the separate Microservices Guide — this page intentionally doesn't go deep into that. That page also has an audit table of every current service's ports and env usage, worth checking before adding a new one so you don't collide with an existing port.

Adding a new environment variable

  • You have two ways to add an environment variable:
  • Shared .env — if you're adding a variable for CoreAPI, use the shared .env file at the root of Quickstart. This is the suggested default, since most CoreAPI-related services already read from it via env_file: - ../../.env (routing up from the compose subfolder to the root .env).
  • Directly in the YAML file — you can also declare the variable inline under a service's environment: block, as seen in some YAML files (e.g. pgadmin's config below). This is more common for service-specific values that don't need to be shared or overridden per environment.
services:
  postgres:
    image: postgres:16-alpine
    networks:
      - internal
    ports:
      - '5432:5432'
    env_file:
      - ../../.env
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres-init:/docker-entrypoint-initdb.d
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER"]
      interval: 20s
      timeout: 20s
      retries: 5
  pgadmin:
    image: dpage/pgadmin4
    networks:
      - internal
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@local.dev
      PGADMIN_DEFAULT_PASSWORD: admin
      PGADMIN_CONFIG_SERVER_MODE: "False"
      PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
    volumes:
      - ./pgadmin/pgadmin-servers.json:/pgadmin4/servers.json
    ports:
      - "5050:80"
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped