Skip to content

Attributes ​

All attributes live in the Rivet namespace (Rivet.Attributes package). They are read by Roslyn at generation time; none of them changes runtime behaviour, with one exception — [RivetConstraints] is a ValidationAttribute and is enforced by validating hosts at runtime.

Discovery ​

AttributeTargetEffect
[RivetContract]static classMarks a contract class; its static readonly RouteDefinition fields become operations.
[RivetClient]classMarks a controller class; all public methods with HTTP attributes ([HttpGet], ...) become operations.
[RivetEndpoint]methodMarks an individual controller/minimal-API method as an operation.
[RivetType]class, enumForces a type to be walked into components/schemas even if no endpoint references it.

Schema metadata ​

AttributeTargetEffect in the spec
[RivetDescription("text")]property, classdescription
[RivetExample("json")]propertyexamples: [value] (3.1 keyword; value parsed as a JSON literal)
[RivetDefault("json")]propertydefault (JSON literal)
[RivetOptional]propertyRemoves the property from required. Nullability alone never does; on a query, header or form parameter a nullable type is already optional.
[RivetReadOnly] / [RivetWriteOnly]propertyreadOnly: true / writeOnly: true
[RivetFormat("fmt")]propertyformat — for custom formats (uri-template, currency, ...) with no dedicated C# type; takes precedence over formats inferred from DataAnnotations
[RivetConstraints(...)]propertymultipleOf, uniqueItems — the two constraints DataAnnotations cannot express. Also a ValidationAttribute: enforced at runtime under validating hosts ([ApiController] model validation, Validator.TryValidateObject); null values pass — pair with [Required]. See Runtime validation
[RivetHeader("Wire-Name")]propertyMarks a contract input-record property as a request header parameter (in: header, original casing preserved; without a name the property name is the header name). The property never enters the JSON schema. Spec-only — header binding stays the host's job. Accept/Content-Type/Authorization are rejected by the emitter (RIV2009).
[RivetScalar]class, struct, recordDeclares an explicit scalar value object: the type must have one public readable non-indexer property named Value and a public constructor accepting its type, whose type becomes the wire primitive with x-rivet-brand. Opt-in replacement for the retired shape-only single-Value-property convention; a Value wrapper without it is an ordinary object schema (invalid shapes fail with RIV1103).
Rivet*EnumConverter<T>enumThe string-enum converter family (requires .NET 8+, used inside [JsonConverter(typeof(...))]): RivetLowerCaseEnumConverter<T> / RivetCamelCaseEnumConverter<T> / RivetSnakeCaseEnumConverter<T> / RivetKebabCaseEnumConverter<T>. The converter class name declares both the string wire and the casing convention for enum wire values; the emitted contract values equal the runtime serializer's wire values by construction. A per-member [JsonStringEnumMemberName] (.NET 9+) overrides the casing. Two members casing to the same wire value fail generation (RIV1106). The bare built-in [JsonConverter(typeof(JsonStringEnumConverter<T>))] keeps exact C# member names.

Operation metadata ​

AttributeTargetEffect
[RivetRequestExample(json, ...)]method, contract fieldRequest body example (optionally named, per media type, or referencing a component example)
[RivetResponseExample(status, json, ...)]method, contract fieldResponse example for a status code
[ProducesFile]contract fieldMarks the endpoint as returning a file download

Standard attributes Rivet also reads ​

  • System.ComponentModel.DataAnnotations: [Required], [Range], [MinLength], [MaxLength], [Length], [StringLength], [RegularExpression], [EmailAddress], [Url] → JSON Schema constraints and formats. [Range] with MinimumIsExclusive/MaximumIsExclusive emits exclusiveMinimum/exclusiveMaximum. [MinLength]/[MaxLength]/[Length] emit minItems/maxItems on a collection and minLength/maxLength otherwise.
  • System.Text.Json: [JsonPropertyName("x")] overrides the camelCased property name.
  • ASP.NET: [Route], [HttpGet]/[HttpPost]/..., [ProducesResponseType], [FromBody]/[FromQuery]/[FromForm]/[FromHeader]/... drive operation shape on controller endpoints. [FromHeader(Name = "X-Api-Key")] maps to an in: header parameter with the attribute's casing (P2 wave 5; previously excluded with the now-retired RIV1005).
  • [Obsolete] → deprecated: true.

None of the constraint metadata is validated by Rivet at runtime — see Runtime Validation.

For scalar null semantics, dictionary keys and unsupported property metadata, see Migrating from v0.42.