Skip to content

Custom code

For APIs where the pattern inference does not produce the client you want, there are three levels of customization, in increasing order of effort.

1. Annotate the document

When a document contains an x-typedrest extension, both the source generator and the command-line tool use it as-is instead of running the inference. Let the tool write a starting point for you:

typedrest-codegen pattern -f myapi.yml

and then edit the result. The extension is a tree of endpoints, keyed by the property names to generate:

x-typedrest:
  contacts:
    kind: collection
    uri: ./contacts
    description: Collection of contacts.
    schema:
      $ref: '#/components/schemas/Contact'
    element:
      kind: element
      description: A specific contact.
      children:
        note:
          kind: element
          uri: ./note
          schema:
            $ref: '#/components/schemas/Note'
        poke:
          kind: action
          uri: ./poke
        picture:
          kind: blob
          uri: ./picture

Every endpoint takes kind, uri, description and children. Some kinds take additional properties:

kind Additional properties Generated endpoint
(omitted) plain endpoint that only holds children
element schema Element endpoint
collection schema, element Collection endpoint
indexer element Indexer endpoint
action Action endpoint
consumer schema Consumer endpoint
producer schema Producer endpoint
function request-schema, response-schema Function endpoint
blob Blob endpoint
upload form-field Upload endpoint
polling schema Polling endpoint
streaming schema Streaming endpoint
streaming-collection schema, element Streaming collection endpoint

The three reactive kinds are never inferred, since an OpenAPI document does not describe the difference between a regular and a streaming response. Annotating the document is the only way to get them.

2. Extend the generated code

All generated classes and interfaces are partial. Adding the methods you need for special cases in a separate file of the same namespace usually beats fighting the generator.

3. Build your own tool

If you need to change how the inference or the code generation itself works, write your own command-line tool on top of these NuGet packages:

TypedRest.CodeGeneration
Parses OpenAPI/Swagger documents and infers TypedRest Endpoints from patterns. Implement IPattern and add it to a PatternRegistry to recognize your own path shapes.
TypedRest.CodeGeneration.CSharp
Generates C# source code for TypedRest .NET clients. Implement IBuilder<TEndpoint> and add it to a BuilderRegistry to change the emitted code, or derive from NamingStrategy to change how types and properties are named.

A minimal tool looks like this:

var reader = new OpenApiStreamReader(new OpenApiReaderSettings().AddTypedRest());
var doc = reader.Read(File.OpenRead("myapi.yml"), out _);

foreach (var type in doc.GenerateTypedRest(new GenerationOptions("MyService")
{
    Namespace = "MyCompany.MyService",
    GenerateInterfaces = true,
    GenerateDtos = true
}))
    type.WriteToDirectory("myclient/");

GenerateTypedRest() takes optional PatternRegistry and BuilderRegistry parameters for the extension points above.

For details see the API documentation.