Manweill / swagger-axios-codegen

swagger client to use axios and typescript
MIT License
306 stars 83 forks source link

ability to strip prefix or suffix from operationId's (which must be globally unique) for method name #107

Closed wizofaus closed 4 years ago

wizofaus commented 4 years ago

Currently codegen takes our swagger and uses the "tags" metadata to generate a typescript class for each resource, for which there are then your typical create/get/list/delete type methods. But in order to achieve this we have to violate the swagger 2 spec which requires globally-unique operationIds. What I'd like is the ability to have codegen strip the suffix off each operationId that matches the resource name (as per the "tags" metadata), so that our operationIds can be, e.g. getFoo, getBar, getWidget but the functions generated are FooService.get(), BarService.get(), WidgetService.get() etc., as per what we have now. Is this a reasonable request? I assume there's no "plugin" mechanism for generating function names? (NB using the 'path', the other alternative for methodNameMode, is not feasible).

Manweill commented 4 years ago

@wizofaus See in ISwaggerOptions.methodNameMode.

wizofaus commented 4 years ago

methodNameMode is either operationId or path, how will that help? Thanks for the super quick reply, but I'm a bit confused why you closed this...

Manweill commented 4 years ago

@wizofaus I think your mean that you need to generate unique method name? Maybe I didn't got it.

wizofaus commented 4 years ago

I mean that I need globally unique operationIds to comply with the swagger spec, e.g. getFoo, getBar, getWidget, updateFoo, updateBar, udpateWidget etc. But the resource name (Foo/Bar/Widget) doesn't need to be included in the method name because it's already in the name of the typescript class: FooService.get FooService.update BarService.get BarService.update WidgetService.get WidgetService.update

i.e. I'd like an option that when generating the methodName that takes the operationId then strips off the "resource name"/service name from the end.

Manweill commented 4 years ago

I got it. I think you can put all the methods in a default Service, like that

class Service{
  static [operationId](){}
}
wizofaus commented 4 years ago

We want to keep the generated client code as it is now - apart from the fact we have a substantial amount of code using it, it looks clean and is well-organized and easy to read. But the only way to achieve it is to violate the swagger 2.0/openapi spec and NOT have globally unique operationIds.

Manweill commented 4 years ago

Emmm....., I am a little confused now. What do you want ,now. Codegen currently has two methods for generating method names.


// use operationId
[tagName]Service {
   static [operationId](){}
}

// use path
[tagName]Service {
   static [last-path](){}
}

Usually we recommend using operationId, because it is the specification of swagger2.0, and it can be customized according to requirements. And then, the tagName is just for grouping

wizofaus commented 4 years ago

I'm saying I'd like

[tagName]Service {
   static [operationId-with-tagName-suffix-removed](){}
}

e.g.

"/v1/foo/{id}":{"get":{"tags":["Foo"],"operationId":"GetFoo" ... "/v1/foo/{id}":{"post":{"tags":["Foo"],"operationId":"UpdateFoo" ... "/v1/bar/{id}":{"get":{"tags":["Bar"],"operationId":"GetBar" ... "/v1/bar/{id}":{"post":{"tags":["Bar"],"operationId":"UpdateBar" ...

should generate

FooService {
   static Get(id){}
   static Update(id, ...){}
}
BarService {
   static Get(id){}
   static Update(id, ...){}
}
Manweill commented 4 years ago

I'm saying I'd like

[tagName]Service {
   static [operationId-with-tagName-suffix-removed](){}
}

it is a bit unreasonable

wizofaus commented 4 years ago

As long as the only operations we have for specifying the methodName are via operationId or path, then there's no way of getting the client stubs we want and complying with the swagger 2.0 specification requiring globally unique operationId's.

I'm happy to put up a PR for it if you accept external contributions.

Manweill commented 4 years ago

Okey, Welcome! But, it only remove methodName's suffix

wizofaus commented 4 years ago

I'll add a new methodNameMode which is operationIdWithoutTagName then?

wizofaus commented 4 years ago

Actually I went with shortOperationId, and it's basically just req.operationId.replace(req.className, ''), though that also required adding className to the IRequestMethods interface. Unfortunately you're not using npm so I haven't quite figured out to compile locally, but hopefully it will work...

Manweill commented 4 years ago

req.operationId.replace(req.className, '')

It is so bad. It should only remove at suffix. you can use trimString() of utils.ts

wizofaus commented 4 years ago

Fair enough, tweaked a few things and put up a PR. I noticed none of your examples had methodNameMode: 'operationId' to test against, not sure if you have a process for creating new examples.

Manweill commented 4 years ago

new example by you.

wizofaus commented 4 years ago

I'm not sure what you're saying, you want me to add one before approving the PR?

Manweill commented 4 years ago

Yes. And then, codegen has a method similar to 'trimSuffix'.

wizofaus commented 4 years ago

I looked at the functions in utils.ts but they were too complex and not particularly efficient for what I needed.

Manweill commented 4 years ago

try it

wizofaus commented 4 years ago

Yep, I did, that's why I went with a simpler method that was suitable to what was needed. I've pushed a new commit with an example.

wizofaus commented 4 years ago

Thanks for merging, having trouble getting it to download the latest version, do you need to republish or something?