TRex is RH TAP's Rest Example
TRex is a full-featured REST 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
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.
Before running TRex for the first time, ensure the prerequisites are installed. For more detailed information on each prerequisite, refer to the prerequisites document.
# 1. build the project
$ go install gotest.tools/gotestsum@latest
$ 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.
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)
make test
make test-integration
The service will be available at http://localhost:8000
For quick testing and development, you can run the service with authentication disabled:
make run-no-authThis starts the service with --enable-authz=false --enable-jwt=false, allowing you to test the API without tokens.
Test the 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} | jqStart the service with authentication enabled:
make runAuthentication in the default configuration is done through the RedHat SSO. You need:
- A Red Hat customer portal user in the right account (created as part of the onboarding doc)
- An access token from https://console.redhat.com/openshift/token
- The
ocmCLI tool available at https://console.redhat.com/openshift/downloads
Step 1: Login to your local service
ocm login --token=${OCM_ACCESS_TOKEN} --url=http://localhost:8000Step 2: List all Dinosaurs
ocm get /api/rh-trex/v1/dinosaursResponse (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"
}
EOFStep 4: Get your Dinosaur
ocm get /api/rh-trex/v1/dinosaursResponse:
{
"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
}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/cacheDeploy 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"
}
EOFTo create your own service based on TRex, you can use the clone command to copy and customize the entire codebase with your service name.
The clone command will:
- Copy the entire TRex project to a new destination directory
- Replace all occurrences of "trex", "rh-trex", and "TRex" with your new service name
- Update import paths to point to your new repository
# Build the trex binary first if you haven't built
make binary
# Clone the codebase to create a new service
./trex clone --name my-service --destination /path/to/my-service --repo-base github.com/my-org
# Example:
./trex clone --name rh-birds --destination /tmp/rh-birds --repo-base github.com/openshift-onlineParameters:
--name: Name of your new service (e.g., "rh-birds", "my-service")--destination: Directory where the new service code will be created--repo-base: Your git repository base URL (e.g., "github.com/my-org")
After the clone completes, you'll see a checklist of next steps. Follow these commands to get your new service running:
# 1. Navigate to your new service directory
cd /path/to/your/new-service
# 2. Install dependencies
go mod tidy
# 3. Build the project
go install gotest.tools/gotestsum@latest
make binary
# 4. Set up the database
make db/setup
# 5. Run database migrations
./your-service-name migrate
# 6. Test the application
make test
make test-integration
# 7. Run your service without authentication required
make run-no-auth
# 8. Verify the service is running
curl http://localhost:8000/api/your-service-name/v1/dinosaurs | jq
# OR
# 9. Run your service with authentication required
make run
# 10. Verify your application is running with authentication required
curl http://localhost:8000/api/your-service-name/v1/dinosaurs | jqThe clone command will output these steps with the correct paths and service names for your convenience.
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 fieldsint- 32-bit integersint64- 64-bit integersbool- Boolean valuesfloat- Floating-point numberstime- Timestamp fields
Field nullability:
- Fields are nullable (pointer types) by default
- Add
:requiredto make a field non-nullable (e.g.,name:string:required) - Add
:optionalto explicitly mark as nullable (e.g.,count:int:optional) - Required fields appear in the OpenAPI
requiredarray
What the generator creates automatically:
- API model (
pkg/api/{kind}.go) - DAO layer (
pkg/dao/{kind}.goandpkg/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.yamlwith new entity references - Runs
make generateto create OpenAPI client code
- Adds plugin import to
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} | jqPlugin 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.
