Skip to content

openshift-online/rh-trex-ai

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

115 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TRex

TRex is RH TAP's Rest Example

Trexxy

TRex is a full-featured REST and gRPC API that persists dinosaurs, making it a solid foundation from which developers can quickly bootstrap new services.

Some of the features included are:

  • Openapi generation
  • CRUD code foundation
  • Standard API guidelines, paging, etc.
  • Test driven development built-in
  • GORM and DB migrations
  • OIDC authentication
  • Responsive control plane
  • Blocking and Non-blocking locks
  • gRPC transport with server-streaming (WatchDinosaurs)
  • Event-driven architecture with PostgreSQL LISTEN/NOTIFY

When looking through the code, anything talking about dinosaurs is business logic, which you will replace with your business logic. The rest is infrastructure that you will probably want to preserve without change.

It's up to you to port future improvements to this project to your own fork. A goal of this project is to become a framework with an upgrade path.

Run for the first time

Before running TRex for the first time, ensure the prerequisites are installed. For more detailed information on each prerequisite, refer to the prerequisites document.

Make a build and run postgres

# 1. build the project

$ go install gotest.tools/gotestsum@latest
$ make proto
$ make binary

# 2. run a postgres database locally in docker

$ make db/setup
$ make db/login

    root@f076ddf94520:/# psql -h localhost -U trex rh-trex
    psql (14.4 (Debian 14.4-1.pgdg110+1))
    Type "help" for help.

    rh-trex=# \dt
    Did not find any relations.

Run database migrations

The initial migration will create the base data model as well as providing a way to add future migrations.

# Run migrations
./trex migrate

# Verify they ran in the database
$ make db/login

root@f076ddf94520:/# psql -h localhost -U trex rh-trex
psql (14.4 (Debian 14.4-1.pgdg110+1))
Type "help" for help.

rh-trex=# \dt
                 List of relations
 Schema |    Name    | Type  |        Owner
--------+------------+-------+---------------------
 public | dinosaurs  | table | trex
 public | events     | table | trex
 public | migrations | table | trex
(3 rows)

Test the application

make test
make test-integration

Running the Service

The REST API will be available at http://localhost:8000 and the gRPC server at localhost:9000.

Option 1: Run Without Authentication (Recommended for Local Development)

For quick testing and development, you can run the service with authentication disabled:

make run-no-auth

This starts the service with --enable-authz=false --enable-jwt=false, allowing you to test the API without tokens.

Test the REST API:

# List all dinosaurs
curl http://localhost:8000/api/rh-trex/v1/dinosaurs | jq

# Create a new dinosaur
curl -X POST http://localhost:8000/api/rh-trex/v1/dinosaurs \
  -H "Content-Type: application/json" \
  -d '{"species": "Tyrannosaurus"}' | jq

# Get a specific dinosaur (replace {id} with actual ID)
curl http://localhost:8000/api/rh-trex/v1/dinosaurs/{id} | jq

Test the gRPC API:

# Install grpcurl if you haven't already
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

# List available services
grpcurl -plaintext localhost:9000 list

# Create a dinosaur
grpcurl -plaintext -d '{"species": "Velociraptor"}' \
  localhost:9000 rh_trex.v1.DinosaurService/CreateDinosaur

# List dinosaurs
grpcurl -plaintext -d '{"page": 1, "size": 10}' \
  localhost:9000 rh_trex.v1.DinosaurService/ListDinosaurs

# Watch for real-time events (server-streaming)
grpcurl -plaintext localhost:9000 rh_trex.v1.DinosaurService/WatchDinosaurs

Option 2: Run With Authentication (Production-like)

Start the service with authentication enabled:

make run

Authentication in the default configuration is done through the RedHat SSO. You need:

Step 1: Login to your local service

ocm login --token=${OCM_ACCESS_TOKEN} --url=http://localhost:8000

Step 2: List all Dinosaurs

ocm get /api/rh-trex/v1/dinosaurs

Response (empty if no dinosaurs exist yet):

{
  "items": [],
  "kind": "DinosaurList",
  "page": 1,
  "size": 0,
  "total": 0
}

Step 3: Create a new Dinosaur

ocm post /api/rh-trex/v1/dinosaurs << EOF
{
    "species": "foo"
}
EOF

Step 4: Get your Dinosaur

ocm get /api/rh-trex/v1/dinosaurs

Response:

{
  "items": [
    {
      "created_at": "2023-10-26T08:15:54.509653Z",
      "href": "/api/rh-trex/v1/dinosaurs/2XIENcJIi9t2eBblhWVCtWLdbDZ",
      "id": "2XIENcJIi9t2eBblhWVCtWLdbDZ",
      "kind": "Dinosaur",
      "species": "foo",
      "updated_at": "2023-10-26T08:15:54.509653Z"
    }
  ],
  "kind": "DinosaurList",
  "page": 1,
  "size": 1,
  "total": 1
}

Option 3: Deploy to OpenShift Local (CRC)

Use OpenShift Local (CRC) to deploy to a local OpenShift cluster.

Prerequisites: Ensure CRC is running locally:

$ crc status
CRC VM:          Running
OpenShift:       Running (v4.13.12)
RAM Usage:       7.709GB of 30.79GB
Disk Usage:      23.75GB of 32.68GB (Inside the CRC VM)
Cache Usage:     37.62GB
Cache Directory: /home/mturansk/.crc/cache

Deploy to CRC:

# 1. Login to CRC
$ make crc/login
Logging into CRC
Logged into "https://api.crc.testing:6443" as "kubeadmin" using existing credentials.

You have access to 66 projects, the list has been suppressed. You can list all projects with 'oc projects'

Using project "ocm-mturansk".
Login Succeeded!

# 2. Deploy the service
$ make deploy

# 3. Login with OCM
$ ocm login --token=${OCM_ACCESS_TOKEN} --url=https://trex.apps-crc.testing --insecure

# 4. Test the deployment
$ ocm post /api/rh-trex/v1/dinosaurs << EOF
{
    "species": "foo"
}
EOF

Run your own service

To create your own service based on TRex, import it as a Go library. See the_big_refactor.md for the full architecture of TRex as an importable library.

Make a new Kind

The generator script creates a complete CRUD entity with plugin-based architecture. This automates most of the boilerplate code needed for a new resource type.

Generate a new entity:

# Basic entity with no custom fields
go run ./scripts/generator.go --kind KindName

# Entity with custom fields (nullable by default)
go run ./scripts/generator.go --kind KindName --fields "name:string,count:int,active:bool"

# Entity with required (non-nullable) and optional (nullable) fields
go run ./scripts/generator.go --kind Rocket --fields "name:string:required,fuel_type:string,max_speed:int:optional"

Supported field types:

  • string - Text fields
  • int - 32-bit integers
  • int64 - 64-bit integers
  • bool - Boolean values
  • float - Floating-point numbers
  • time - Timestamp fields

Field nullability:

  • Fields are nullable (pointer types) by default
  • Add :required to make a field non-nullable (e.g., name:string:required)
  • Add :optional to explicitly mark as nullable (e.g., count:int:optional)
  • Required fields appear in the OpenAPI required array

What the generator creates automatically:

  • API model (pkg/api/{kind}.go)
  • DAO layer (pkg/dao/{kind}.go and pkg/dao/mocks/{kind}.go)
  • Service layer with event handlers (pkg/services/{kind}.go)
  • HTTP handlers (pkg/handlers/{kind}.go)
  • Presenters (pkg/api/presenters/{kind}.go)
  • Database migration (pkg/db/migrations/YYYYMMDDHHMM_add_{kinds}.go)
  • OpenAPI specification (openapi/openapi.{kinds}.yaml)
  • Integration tests (test/integration/{kinds}_test.go)
  • Test factories (test/factories/{kinds}.go)
  • Plugin registration (plugins/{kinds}/plugin.go) - auto-registers routes, controllers, and presenters
  • Automatic updates:
    • Adds plugin import to cmd/trex/main.go
    • Adds migration to pkg/db/migrations/migration_structs.go
    • Updates openapi/openapi.yaml with new entity references
    • Runs make generate to create OpenAPI client code

After generation, build and test:

# 1. Build the binary
make binary

# 2. Set up the database
make db/teardown
make db/setup

# 3. Run migrations
./trex migrate

# 4. Run the server
make run-no-auth

# 5. Test the new entity
curl -X POST http://localhost:8000/api/rh-trex/v1/{kinds} \
  -H "Content-Type: application/json" \
  -d '{"species": "example"}' | jq

curl http://localhost:8000/api/rh-trex/v1/{kinds} | jq

Plugin Architecture Benefits:

  • Reduction in manual steps - no need to manually edit routes, controllers, or service locators
  • Self-contained entities - all wiring for an entity lives in its plugin file
  • Auto-discovery - plugins register themselves via init() functions
  • Type-safe - compile-time checks for service access

For more detailed information about the generator and plugin system, see CLAUDE.md.

About

Red Hat's AI-enabled Trusted REST Example

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Go 81.0%
  • Go Template 14.7%
  • Makefile 2.7%
  • Shell 0.8%
  • JavaScript 0.6%
  • HTML 0.1%
  • Dockerfile 0.1%