# Step 1 - Define the data contract

> For the complete documentation index, see [llms.txt](https://docs.temporal.io/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.

> Plan a purchase approval Nexus Service and write its data contract before any implementation, so every language shares one definition.

Start with the contract, not the code.

The contract is the only thing a caller and a handler share. Everything else — which language each side is written in, whether an Operation is backed by a Workflow or an Activity, which Task Queue the Worker polls — is private to one side and can change without the other side knowing.

## Why the contract comes first

Writing the contract first is what makes the Service polyglot.

**Every sample in this walkthrough, in every language, is generated from this one contract.** A Go caller can call a Java handler. A TypeScript caller can call a Python handler. What language a side is written in has no bearing on whether the two can talk — the only thing that has to match is the contract they were both generated from. Each side picks whatever language suits it, and as long as both were built against this contract, they interoperate.

That is why the contract comes before any implementation. It is written once, in no particular language, and every implementation in this walkthrough is generated from it.

## Plan the Operations

As with all API design, work backwards from what callers need, not from what your Workflow happens to do.

For the approval problem, callers need to check whether a purchase needs approval at all, start an approval and learn its outcome, nudge a pending approval, attach supporting information to a purchase, submit a decision, and be notified when the decision is final. That produces six Operations:

| Operation | Input | Output | Added in |
| --- | --- | --- | --- |
| `checkApprovalRequired` | Item id, requester, amount | Whether approval is needed, and the threshold applied | Step 3 |
| `requestApproval` | Item id, requester, amount | `APPROVED` or `DENIED` | Step 4 |
| `remindApprover` | Approval id | Nothing | Step 7 |
| `submitDecision` | Approval id, decision | Confirmation of the recorded decision | Step 7 |
| `attachApprovalContext` | Item id, requester, amount, note | Nothing | Step 8 |
| `notifyRequester` | Requester, decision | Nothing | Step 9 |

Three of those are worth explaining now, because they are easy to get wrong. They also introduce the three shapes an Operation can take, named here and chosen per Operation in [step 3](/develop/java/nexus/development-walkthrough/choose-backing-implementation):

**`checkApprovalRequired` answers a question without starting anything.** A small purchase may not need approval, and finding that out should not create an approval, a Workflow, or any durable record. This is the synchronous case: the Operation applies a spend threshold and returns the answer during the call, so a caller can skip the rest of this Service entirely.

**`requestApproval` returns the final decision.** It does not return an approval id for the caller to poll. The Operation is Workflow-backed, so it completes when that Workflow returns, and the Workflow's return value *is* the Operation's result. The caller awaits the Operation and receives `APPROVED` or `DENIED`.

**`attachApprovalContext` does not require the approval to exist.** Supporting information — a justification, a link to a quote, a manager's note — is produced by a different system than the one requesting approval, and the two messages can arrive in either order. The Operation is written so that either order works, which means both might have to start the approval workflow. Since this message might have to start the workflow, its input needs to include the purchase details so that the workflow has enough information to start. [Step 8](/develop/java/nexus/development-walkthrough/send-messages#attach-information-before-the-approval-exists) covers this in detail.

## Contract design rules

An Operation's input and output are each optional, but when present each must be an **object type**. If the input is only a single variable a class wrapping that is still required. This allows you to add a field later without breaking the wire format. Conversely, though, returning nothing at all is fine, which `remindApprover` does.

Keep the types **forward-compatible** if you change the contract. Callers and handlers deploy independently and will run different versions of the contract at the same time. Adding an optional field is safe; making an existing field required, or removing one, is not.

## Write the contract

Contracts are modeled with JSON Schema 2020-12. Each definition file is one of two kinds, decided by what sits at its root:

- **Nexus document** - the root carries a `nexusrpc: '1.0.0'` marker and acts as an envelope, with Services and their Operations at the top level and types under `$defs`. Only this kind can declare a Service.
- **Pure JSON Schema** - the root is itself a type, with reusable types under `$defs`. No Service or Operation declarations, just data models shared across languages.

A file is one or the other, never both. A contract can span several files, with a Nexus document pulling in types from pure-schema files through `$ref`.

The approval contract declares a Service with six Operations, so its entry file is a Nexus document.

**[Definition files](/nexus/client-code-generator#definition-files)** documents both flavors in full, with the supported subset of JSON Schema and a worked example to model this contract on. Read it before writing the approval contract.

## Next

**[Step 2 - Generate code from the contract](/develop/java/nexus/development-walkthrough/generate-code)** - turn the contract into the typed code both sides use.

Back to the [Microservice Development Walkthrough overview](/develop/java/nexus/development-walkthrough).

> **💡 Tip:**
> RESOURCES
>
> - [Nexus Client Code Generator](/nexus/client-code-generator) for the contract format and the supported JSON Schema subset.
> - [Nexus Services](/nexus/services) for what a Service contract is and how it is shared.
>
