Integration model
jtWMS offers two ways in and out: a REST API for asking and changing, and events for being told what changed.
REST first
Section titled “REST first”Every feature is available through the REST API, and the jtWMS apps use the same API. Every API
route is under /api/v1/ (sign-in uses the standard OAuth endpoints under /connect/), every error
has one format, and the largest lists are paged. Each service publishes an OpenAPI document, and the
gateway serves an interactive reference at /docs. Clients should ignore response fields they don’t
recognise. See API & integration.
Events after changes
Section titled “Events after changes”Today the warehouse configuration and catalog services publish events, such as
jtWMS.Catalog.Events.V1.ProductCreated or
jtWMS.WarehouseConfig.Events.V1.StorageNodeCascadeDeleted. Every product change publishes one, and
so does every change to facilities, zone profiles, zones, the storage layout, locations and
equipment, except removing a single location from a zone. Changes to users, roles, API keys, plans
and webhook subscriptions publish no events.
- Never lost. An event is written in the same database transaction as the change it describes. If the change is saved, its event is saved with it and published afterwards, even if the service restarts in between. If the change fails, there is no event.
- At least once. Because publishing is retried until it succeeds, an event can occasionally be delivered more than once. Every event has an ID that stays the same on every attempt, so consumers can recognise repeats.
- Full state. Most events carry the complete record as it was after the change, not just the fields that changed, so a consumer can act on one event without reading the record back. The exceptions are a PLC address change (the node’s IDs, code and old and new address), locations assigned to a zone (the zone and the IDs of the locations added), equipment node events (a configuration update carries the node’s IDs, type, code and configuration; the others carry the node without its configuration), a bulk equipment connection create (the connection IDs) and a cascade delete (the IDs it deleted).
- Deletes are status changes. Deleting a record publishes its status-changed event with the deleted status, rather than a separate deleted event. The exception is a cascade delete of the storage layout, which publishes one event listing the IDs of every node and location it deleted.
Versioning
Section titled “Versioning”Every event type carries its version in its name (.Events.V1.). The versioning policy is:
| Change | How it ships |
|---|---|
| A new optional field | In place, in the same version. Consumers ignore fields they don’t know. |
| A new value in an enumeration | In place, in the same version. Consumers treat a value they don’t know as a default. |
| Removing, renaming or retyping a field | A new version, such as V2, published alongside the old one for a deprecation window, so consumers can move at their own pace. |
Consumers should read only the fields they need and ignore the rest, so additive changes never break them.
The policy is enforced, not only written down. Every change to jtWMS’s API and event definitions is compared automatically with the current version before it ships, and a change that would break an existing client or consumer is stopped. The one exception is retiring an old version at the end of its deprecation window. An event appears in the events reference, and webhooks can subscribe to it, only once a service publishes it.
Webhooks
Section titled “Webhooks”Webhooks are how events reach your systems. A subscription names an HTTPS endpoint and the event
types it wants, by exact name or a whole domain. jtWMS then sends each matching event as a signed
POST, retries failures with increasing delays, and keeps deliveries that never succeeded so you
can redeliver them. Deliveries are at least once and can arrive out of order, so deduplicate by
delivery ID and use each event’s time and full state to decide which is newer. See
Webhooks, in particular At-least-once delivery
and Event types.
Correlation IDs
Section titled “Correlation IDs”Every request carries a correlation ID. Send your own in the X-Correlation-Id header, or jtWMS
generates one, and every response echoes it. The same ID follows the request through the services
that handle it, into their logs, onto the audit entries it writes and the events it publishes, and
into the error body if it fails. Quote it to support to trace a request end to end. See
Correlation IDs.