Search code examples
angulartypescriptasp.net-core

Nswag generates duplicate versions of get method


I have .net core web api basic project. I added swagger to it. Now I want to generate typescript client to use it in angular. I am using NSwag studio. The APIs look like:

public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }

When I generated the typescript client using NswagStudio it generates two versions of get method which cause an error in typescript because of not support method overloading. I want to generate Client class for every controller so, I set Operation Generation Mode: "MultipleClientsFromPathSegments". The generated result is:

export class ApiClient {
  valuesGet(): Observable<string[]> {}
 protected processValuesGet(response: HttpResponseBase): Observable<string[]>{}

valuesPost(value: string | null | undefined): Observable<void>{}
protected processValuesPost(response: HttpResponseBase): Observable<void>{}

valuesGet(id: number): Observable<string>{}
protected processValuesGet(response: HttpResponseBase): Observable<string>{}
}

I want to generate the first get with name "getAll" as it supposes to be. anybody have idea. Thanks


Solution

  • It seems that you are using a path based generation mode like 'SingleClientFromPathSegments'. This generation mode creates one single typescript file and uses the path to name the functions. Since you have the same path for Get() and Get(int id) nswag generates two functions with the same name. This is a problem because typescript does not support function overloading.

    Option 1:

    You could use a different generation mode, for example 'SingleClientFromOperationId'. This generation Mode uses the name of your methods to generate the typescript functions. This should result in an valid typescript file and your functions should be named values_Get() and values_Get2(). To get more expressive function names you could rename the c# method Get() to GetAll(). This allows you to keep your routes and get expressive function names in your typescript client.

    You can change the generation mode in your nswag.json file using the NSwagStudio or by editing the file via a text editor. In NSwagStudio this setting is located in the Typscript Client Settings. In the nswag.json file the setting is called 'operationGenerationMode';

    Your controller would like this:

    public class ValuesController : ControllerBase {
            // GET api/values
            [HttpGet]
            public ActionResult<IEnumerable<string>> GetAll(){
                return new string[] { "value1", "value2" };
            }
    
            // GET api/values/5
            [HttpGet("{id}")]
            public ActionResult<string> Get(int id){
                return "value";
            }
    
            // ...
    }
    

    Option 2:

    You could change your Routing like mentioned in Quails4Eva's answer