# Comparison guide: OpenAPI/Swagger C# client generation
Source: https://speakeasy.com/docs/sdks/languages/csharp/oss-comparison-csharp

import { Table } from "@/mdx/components";



Speakeasy produces idiomatic SDKs in various programming languages, including C#. The Speakeasy approach to SDK generation prioritizes a good developer journey to enable API providers to focus on developing a streamlined experience for users.

In this article, we'll compare creating a C# SDK using Speakeasy to creating one using the open-source OpenAPI Generator. The table below is a summary of the comparison:

<Table
  data={[
    {
      feature: "Framework Support",
      speakeasy: "⚠️ Limited to .NET 5+",
      openapiGenerator:
        "✅ Wider range (.NET Framework 4.7, .NET Standard 1.3-2.1, .NET 6+)",
    },
    {
      feature: ".NET Features",
      speakeasy: "✅ Full async/await support, interfaces for DI",
      openapiGenerator: "⚠️ Basic async/await support",
    },
    {
      feature: "Dependencies",
      speakeasy: "✅ Minimal - Only Newtonsoft.Json and NodaTime",
      openapiGenerator:
        "❌ Multiple dependencies including JsonSubTypes, Newtonsoft.Json, RestSharp, Polly, System.Web",
    },
    {
      feature: "Code Style",
      speakeasy: "✅ Modern, idiomatic C# with object initializers",
      openapiGenerator:
        "⚠️ Traditional C# with constructors and property setters",
    },
    {
      feature: "HTTP client",
      speakeasy: "✅ Uses built-in System.Net.Http",
      openapiGenerator: "❌ Relies on third-party RestSharp library",
    },
    {
      feature: "Request retry",
      speakeasy:
        "✅ Built-in configurable retry support with multiple strategies",
      openapiGenerator: "❌ No built-in retry support",
    },
    {
      feature: "Model implementation",
      speakeasy:
        "✅ Modern, concise approach using nullable types and attributes",
      openapiGenerator:
        "⚠️ Traditional approach with more verbose implementations",
    },
    {
      feature: "Serialization",
      speakeasy: "✅ Clean approach using JsonProperty attributes directly",
      openapiGenerator:
        "⚠️ More complex approach using DataContract and DataMember attributes",
    },
    {
      feature: "Documentation",
      speakeasy:
        "✅ Comprehensive documentation with detailed examples and error handling",
      openapiGenerator:
        "⚠️ Basic documentation focusing on setup and API routes",
    },
    {
      feature: "Error handling",
      speakeasy: "⚠️ Generic exceptions with stack traces",
      openapiGenerator: "✅ More descriptive custom exceptions",
    },
    {
      feature: "Customization",
      speakeasy: "✅ Supports hooks and custom configurations",
      openapiGenerator: "❌ Limited customization options",
    },
  ]}
  columns={[
    { key: "feature", header: "Feature/Aspect" },
    { key: "speakeasy", header: "Speakeasy" },
    { key: "openapiGenerator", header: "OpenAPI Generator" },
  ]}
/>

You can explore the Speakeasy [C# SDK documentation](/docs/languages/csharp/methodology-csharp) for more information.

For a detailed technical comparison, read on!

## Installing the CLIs

We'll start by installing the Speakeasy CLI and the OpenAPI Generator CLI.

### Installing the Speakeasy CLI

You can install the Speakeasy CLI by following the installation instructions [here](/docs/speakeasy-reference/cli/getting-started).

After installation, you can check the version to ensure the installation was successful:

```bash
speakeasy -v
```

If you encounter any errors, take a look at the [Speakeasy SDK creation documentation](/docs/sdks/create-client-sdks).

### Installing the OpenAPI Generator CLI

Install the OpenAPI Generator CLI by running the following command in a terminal:

```bash
curl -o openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.2.0/openapi-generator-cli-7.2.0.jar
```

## Downloading the Swagger Petstore specification

We need an OpenAPI specification YAML file to generate SDKs. We'll use the Swagger Petstore specification, which you can find at [https://petstore3.swagger.io/api/v3/openapi.yaml](https://petstore3.swagger.io/api/v3/openapi.yaml).

In a terminal in your working directory, download the file and save it as `petstore.yaml` with the following command:

```bash
curl -o petstore.yaml https://petstore3.swagger.io/api/v3/openapi.yaml
```

## Validating the specification file

Let's validate the spec using both the Speakeasy CLI and OpenAPI Generator.

### Validating the Specification File Using Speakeasy

Validate the spec with Speakeasy using the following command:

```bash
speakeasy validate openapi -s petstore.yaml
```

The Speakeasy validator returns the following:

```bash

╭────────────╮╭───────────────╮╭────────────╮
│ Errors (0) ││ Warnings (10) ││ Hints (72) │
├────────────┴┘               └┴────────────┴────────────────────────────────────────────────────────────╮
│                                                                                                        │
│ │ Line 250: operation-success-response - operation `updatePetWithForm` must define at least a single   │
│ │ `2xx` or `3xx` response                                                                              │
│                                                                                                        │
│   Line 277: operation-success-response - operation `deletePet` must define at least a single `2xx` or  │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   Line 413: operation-success-response - operation `deleteOrder` must define at least a single `2xx` o │
│   r                                                                                                    │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   Line 437: operation-success-response - operation `createUser` must define at least a single `2xx` or │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   Line 524: operation-success-response - operation `logoutUser` must define at least a single `2xx` or │
│   `3xx` response                                                                                       │
│                                                                                                        │
│   ••                                                                                                   │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 ←/→ switch tabs  ↑/↓ navigate  ↵ inspect  esc quit

```

The Speakeasy CLI validation result gives us a handy tool for switching between the errors, warnings, and hints tabs with the option to navigate through the results on each tab.

In this instance, Speakeasy generated ten warnings. Let's correct them before continuing.

Notice that some of the warnings contain a `default` response. For completeness, we'd like to explicitly return a `200` HTTP response. We'll make the following modifications in the `petstore.yaml` file.

When the `updatePetWithForm` operation executes successfully, we expect an HTTP `200` response with the updated `Pet` object to be returned.

Insert the following after `responses` on line 250:

```yaml
"200":
  description: successful operation
  content:
    application/xml:
      schema:
        $ref: "#/components/schemas/Pet"
    application/json:
      schema:
        $ref: "#/components/schemas/Pet"
```

Similarly, following successful `createUser` and `updateUser` operations, we'd like to return an HTTP `200` response with a `User` object.

Add the following text to both operations below `responses`:

```yaml
"200":
  description: successful operation
  content:
    application/xml:
      schema:
        $ref: "#/components/schemas/User"
    application/json:
      schema:
        $ref: "#/components/schemas/User"
```

Now we'll add the same response to four operations. Copy the following text:

```yaml
"200":
  description: successful operation
```

Paste this response after `responses` for the following operations:

- `deletePet`
- `deleteOrder`
- `logoutUser`
- `deleteUser`

We are left with three warnings indicating potentially unused or orphaned objects and operations.

For unused objects, locate the following lines of code and delete them:

```yaml
Customer:
  type: object
  properties:
    id:
      type: integer
      format: int64
      example: 100000
    username:
      type: string
      example: fehguy
    address:
      type: array
      xml:
        name: addresses
        wrapped: true
      items:
        $ref: "#/components/schemas/Address"
  xml:
    name: customer
Address:
  type: object
  properties:
    street:
      type: string
      example: 437 Lytton
    city:
      type: string
      example: Palo Alto
    state:
      type: string
      example: CA
    zip:
      type: string
      example: "94301"
  xml:
    name: address
```

To remove the unused request bodies, locate the following lines and delete them:

```yaml
requestBodies:
  Pet:
    description: Pet object that needs to be added to the store
    content:
      application/json:
        schema:
          $ref: "#/components/schemas/Pet"
      application/xml:
        schema:
          $ref: "#/components/schemas/Pet"
  UserArray:
    description: List of user object
    content:
      application/json:
        schema:
          type: array
          items:
            $ref: "#/components/schemas/User"
```

Now if you validate the file with the Speakeasy CLI, you'll notice there are no warnings:

```
╭────────────╮╭──────────────╮╭────────────╮
│ Errors (0) ││ Warnings (0) ││ Hints (75) │
├────────────┴┴──────────────┴┘            └─────────────────────────────────────────────────────────────╮
│                                                                                                        │
│ │ Line 51: missing-examples - Missing example for requestBody. Consider adding an example              │
│                                                                                                        │
│   Line 54: missing-examples - Missing example for requestBody. Consider adding an example              │
│                                                                                                        │
│   Line 57: missing-examples - Missing example for requestBody. Consider adding an example              │
│                                                                                                        │
│   Line 65: missing-examples - Missing example for responses. Consider adding an example                │
│                                                                                                        │
│   Line 68: missing-examples - Missing example for responses. Consider adding an example                │
│                                                                                                        │
│   •••••••••••••••                                                                                      │
└────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 ←/→ switch tabs  ↑/↓ navigate  ↵ inspect  esc quit
```

### Validating the specification file using the OpenAPI Generator

OpenAPI Generator requires Java runtime environment (JRE) version 11 or later installed. Confirm whether JRE is installed on your system by executing the following command:

```bash
java --version
```

If Java is installed, information about the version should be displayed similar to this:

```bash
java 17.0.8 2023-07-18 LTS
Java(TM) SE Runtime Environment (build 17.0.8+9-LTS-211)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.8+9-LTS-211, mixed mode, sharing)
```

If you get an error or the JRE version is older than version 11, you need to update or [install Java](https://docs.oracle.com/goldengate/1212/gg-winux/GDRAD/java.htm#BGBFJHAB).

Now you can validate the `petstore.yaml` specification file with OpenAPI Generator by running the following command in the terminal:

```bash
java -jar openapi-generator-cli.jar validate -i petstore.yaml
```

The OpenAPI Generator returns the following response, indicating no issues detected.

```
Validating spec (petstore.yaml)
No validation issues detected.
```

Now that we have made the `petstore.yaml` file more complete by fixing the warnings, let's use it to create SDKs.

## Creating SDKs

We'll create C# SDKs using Speakeasy and OpenAPI Generator and then compare them.

### Creating an SDK with Speakeasy

To create a C# SDK from the `petstore.yaml` specification file using Speakeasy, run the following command in the terminal:

```bash