Event-Driven APIs 2026 — A Field Guide is the work that makes the systems talk. The API is the contract between the producer and the consumer; the contract is what determines whether the integration succeeds or fails. This guide is the field-tested pattern for AsyncAPI in a production context.
REST patterns
REST is still the default. The patterns that work:
- Resource-oriented URLs.
/customers/{id}/orders, not/getCustomerOrders?id=123. - HTTP verbs. GET (read), POST (create), PUT/PATCH (update), DELETE (remove).
- Status codes. 200 (OK), 201 (Created), 204 (No Content), 400 (Bad Request), 404 (Not Found), 500 (Server Error).
- Content negotiation.
Accept: application/json. - Versioning. URL versioning (
/v1/) or header versioning (Accept: application/vnd.api+json;version=1).
The OpenAPI spec drifts from the implementation within a week of every release. The only fix is generation, not maintenance. Generate the spec from the routes, the validation rules, and the response schemas.
For the broader REST patterns, see the REST API definitive guide.
GraphQL patterns
GraphQL is the right tool when the client has many views of the same data and the network is the bottleneck. The patterns:
- Schema-first design. Define the schema first; resolve against it.
- DataLoader for N+1. Batch fetches across resolvers.
- Persisted queries. Pre-register common queries; reject the rest.
- Subscriptions for real-time. WebSocket-based subscriptions over the same schema.
type Query {
customer(id: ID!): Customer
customers(filter: CustomerFilter): [Customer!]!
}
type Mutation {
createCustomer(input: CustomerInput!): Customer!
updateCustomer(id: ID!, input: CustomerInput!): Customer!
}
type Subscription {
orderStatus(orderId: ID!): OrderStatus!
}
type Customer {
id: ID!
name: String!
email: String!
orders(filter: OrderFilter): [Order!]!
}
gRPC and protocol buffers
gRPC is the right tool for service-to-service communication. The patterns:
- Strong typing. Protocol buffers define the contract.
- Streaming. Server, client, and bidirectional streaming.
- Code generation. Generated clients in 11+ languages.
- HTTP/2. Multiplexing, header compression.
syntax = "proto3";
package ar.v1;
service ARService {
rpc ListInvoices(ListInvoicesRequest) returns (ListInvoicesResponse);
rpc CreateInvoice(CreateInvoiceRequest) returns (Invoice);
rpc StreamInvoices(StreamInvoicesRequest) returns (stream Invoice);
}
message Invoice {
string refnbr = 1;
string customer_id = 2;
string docdate = 3;
double curyorigdocamt = 4;
string status = 5;
}
Webhooks for event-driven APIs
Webhooks are the right tool when the consumer wants to be notified about events. The patterns:
- Signature verification. Every webhook includes a signature header; the consumer verifies it.
- At-least-once delivery. Webhooks are retried; the consumer must be idempotent.
- Quick ack. The consumer returns 200 fast; processes async.
- Dead-letter queue. Failed deliveries go to a DLQ; replay later.
For the broader webhook patterns, see the webhooks vs polling guide.
Contract testing
The consumer-producer contract must be tested. The patterns:
- Pact (consumer-driven). The consumer defines the contract; the producer verifies.
- Schema validation (OpenAPI, JSON Schema). The producer publishes the schema; the consumer validates responses against it.
- Mock servers (Prism, Postman mocks). The consumer mocks the producer for local dev.
An OpenAPI spec is a contract. A contract that is not tested is a lie. Run the contract test in CI for both the consumer and the producer. A failing contract test is a release blocker.
Wrapping up
REST for general use, GraphQL when the client has many views, gRPC for service-to-service, webhooks for events. The contract is the API; the contract test is the proof. Get the contract right and the integration works. Get the contract test right and the integration stays right.
Wrapping up
That is the working approach I use on Acumatica projects. The same patterns show up whether you are in Nairobi, Johannesburg, Kigali, Lusaka or Harare — and they are the things that keep work moving when an upgrade lands at 6 PM on a Friday. If you are stuck on something specific, reach out or keep reading through the rest of the Acumatica blog.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.