Your First Nenu Program
- The runnable receives its Request and Response contracts from App Marché metadata.
- It fetches the room and payer, constructs an Expense, saves it, and returns Response.
- This first example is intentionally complete; later pages explain every line separately.
Goal And Contracts
The runnable creates one expense for the room. Its metadata provides a Request with room_id, payer_id, title, and amount. Its Response contains the saved expense. Do not declare type Request or type Response in source.
| Input | Type | Meaning |
|---|---|---|
request.room_id | string | The one room receiving the expense. |
request.payer_id | string | The existing platform user who paid. |
request.title | string | A short description such as Internet. |
request.amount | number | The amount paid. |
Complete Runnable
1need {2 room = Room(request.room_id)3 payer = User(request.payer_id)4}56Expense expense = Expense {7 room_id: room.id8 payer9 title: request.title10 amount: request.amount11 note: ?12 receipt: ?13 status: ExpenseStatus.Open14}1516save(expense)17return Response { expense }Walkthrough
needfetches the existingRoomand platform-providedUserbefore ordinary runnable statements execute.Expense expensedeclares a local namedexpensewith an explicit entity type.Expense { ... }constructs a value.room_id: room.idis an explicit field expression, while barepayeris shorthand forpayer: payer.save(expense)persists the new record. Save always uses parentheses.return Response { expense }satisfies the metadata-defined response contract on the successful path.
Expected Result
Given a valid room, payer, title, and amount, the runnable creates one durable Expense and returns it in the expense response field. A missing required fetch or an incompatible request field is a hard failure rather than an absent partial result.
Common Mistakes
| Wrong | Correct | Reason |
|---|---|---|
| Declare the platform User type locally | User(request.payer_id) | User is supplied by the platform. |
new Expense { ... } | Expense { ... } | Nenu has no new keyword. |
needs { ... } | need { ... } | The keyword is singular. |
save expense | save(expense) | Save requires parentheses. |
respond { expense } | return Response { expense } | The old respond statement was removed. |
