Generating C# client from swagger file

Does ServiceStack have the tooling to generate typed C# client from Swagger/Open API JSON file?

By this, I don’t mean adding swagger support to a ServiceStack service but generating a typed C# client from an external service (not made with ServiceStack) with a swagger file definition.

Thanks.

No, our Service Client story already adopts the most optimal strategy for ServiceStack APIs, code generating client proxies from a spec is deficient in comparison and there’s no justification why we’d invest any effort in it.

I managed to create a fully typed client supporting async with ServiceStack in less than 500 lines of code (497 to be exact).

That compares to the 6888 lines of code generated by a tool processing swagger file. On top of it, their generated client didn’t support authorization.

Basically, it took me less time to program the client using ServiceStack than it took me to figure out how to install the swagger tooling and wire in the authorization supports, etc.

The code is easier to understand and you understand at a glance what it’s doing.

Good job. You have an amazing product.

1 Like

The only thing I’d like to improve is this (actually maybe it’s not a good idea).

On the following endpoint their API return the following json:

{"code":200}

So I created the following type to map the response result:

public class TransferAgentHttpStatusCode
{
    public HttpStatusCode Code { get; set; }
}

And use it as the IReturn:

[Route("/uploads/{UploadId}/pause")]
public class PauseUpload : IPost, IReturn<TransferAgentHttpStatusCode>
{
    [IgnoreDataMember]
    public string UploadId { get; set; }
}

In cases like these is there a way to unwrap directly the HttpStatusCode like this:

[Route("/uploads/{UploadId}/pause")]
public class PauseUpload : IPost, IReturn<HttpStatusCode>
{
    [IgnoreDataMember]
    public string UploadId { get; set; }
}

Maybe that’s a bad idea and it’s better to keep it as-is?

No, the schema must match the wire format exactly and Services can only return reference types.

If I understand correctly you would keep it as-is:

[Route("/uploads/{UploadId}/pause")]
public class PauseUpload : IPost, IReturn<TransferAgentHttpStatusCode>
{
    [IgnoreDataMember]
    public string UploadId { get; set; }
}

Sorry English is my second language I can’t always infer the meaning correctly…

Right as a DTO mathing the wire format. Also HttpStatusCode isn’t exhaustive where they could conceivably return a Status code not in the enum breaking your API, so I’d personally use an int instead.

1 Like