Repository navigation
Conversation
A resource method can take the items of its last list as arguments, take a one-field record as its field, and return one field of the response. The Stream's publish takes values and returns the last offset.
This was referenced Oct 28, 2026
Contributor
Author
|
Moved to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
This PR adds
@nexus.varargs,@nexus.unwrapand@nexus.result-field, which turn the Stream'spublish(records: list<append-record>) -> append-records-responseintopublish(*values) -> int.@nexus.unwrapgoes on a record with one field that isn't omitted. A resource method takes that field's type in place of the record, and wraps each value in the record when it builds the request. A generic record unwraps to its type parameter. The model and the wire keep the record.@nexus.varargsgoes on a resource method whose last parameter is a list. The method takes the list's items as positional arguments, andnamegives their API name, since name binding uses the WIT name. Python takes*valuesand makes the other parameters keyword-only, TypeScript takes...values, .NET takesparams T[] values, and Go takesvalues ...T.@nexus.result-fieldmakes a resource method return one field of the response. Anoptionfield of a proto with no presence returns its zero value when the response leaves it unset, sopublishreturns0for an empty publish. A field with presence returns its absence. Go returns the zero value in a future of its own.nexgen refuses
@nexus.unwrapon a record with another number of fields, with@nexus.flatten-in-api, or on a whole operation input. It refuses@nexus.varargson a method whose last parameter isn't a list, on an operation, or with anameof another parameter. It refuses@nexus.result-fieldthat names no field of the response, on a method whose result isn't a record, or with an output transform on the bound operation.The stream sample takes all three, so
publishispublish(*values: BodyT) -> intin Python,publish(...values: BodyT[]): Promise<Long>in TypeScript andTask<long> PublishAsync(params TBody[] values)in .NET. The writer'swrite_recordstakes the values of its records too. A new sample,batch-service, shows all three in the four languages, with a JSON result field that keeps its absence.It sits on #331. The stack is #308, #310, #311, #297, #296, #303, #304, #309, #318, #319, #320, #321, #322, #323, #324, #325, #326, #327, #328, #329, #330, #331, then this PR.
Why?
The Stream API of the proposal has
publish(*values: T) -> int. The WIT keeps the request and the response of the proto, so the three directives map one to the other, and each is general.The design also unwrapped the parameters of an operation function. This PR unwraps the resource method parameters only, since the facade calls the operation functions with records.
Java has no resource methods, so nothing changes for it.
How did you test it?
A Python test publishes two values and checks the wrapped records and the last offset, and that an empty publish answers
0. A TypeScript test does the same withLong. A .NET compile check publishes two values. Python, TypeScript and Go tests add items to abatch-servicebatch and check the wrapped items, the field, and the absent field of an empty add (None,undefined, and""in Go). A .NET compile check calls it. A unit test checks the directives ofpublish, and rejection fixtures cover each refusal.cargo validatepasses.