Open abillingsley opened 4 years ago
axios
, rxjs
, angular
are all different http client libraries
react
, on the other hand, is view layer, agnostic of http. I don't think it's even feasible to have a generator for every combination of (view, http client). Do you want to use react with axios? or with fetch? or anything else out there?
I understand your perspective. Is the issue with the proposed name? Perhaps if instead of proposing the name is typescript-react-hooks
we called it typescript-fetch-hooks
would this be more agreeable?
I agree that axios and fetch are http clients. I have a hard time seeing rxjs and angular as http clients, rather I see these as libraries or frameworks that among many other things have provided an opinion on http.
I agree that React is a view library but React is an incredibly popular view library in the front end ecosystem. Within the React Ecosystem hooks are becoming the standard way to interact with state, http, etc. From my perspective, it seems reasonable to provide access to the open api client libraries using an api that makes sense to developers since this can only improve the adoption of open api.
I'd argue providing a hooks based api is similar to providing the necessary interfaces to enable Open API with Angular. An Angular Developer could just as easily use the typescript-fetch
or typescript-axios
generator then provide their own services ontop to enable these lower-level APIs to work within the angular dependency injection system. Currently within the React ecosystem developers who want to leverage hooks with open api need to wrap open api code generated using typescript-fetch
or typescript-axios
in custom code. Why not provide the same conveniences to React developers that have been provided to the Angular developers?
I 100% agree it would be hard if not impossible to provide generators for React + every http client available but I think starting with the common choices for react developers would be good enough.
@abillingsley Hmmm... Why new generator instead of -p useReactHooks=true
option to existen TypeScript client?
@ybelenko I think it depends on the level of abstraction you want to create. For example, would you also want to support -p useVueHooks=true
or similar within the typescript-fetch
generator? perhaps. My suggestion in the issue description was based on the convention I thought I was seeing with typescript-[angular|angularjs|aurelia]
. It seems the intent is to centralize around http client implementation (axios, fetch, angular's httpclient, etc) in this case I can definitely see an argument for making the hooks abstraction part of the existing generator(s) like typescript-fetch. I think I would need to defer to the openapi team on where to put the generated code for react hooks or similar convenience interfaces.
At the end of the day whether I run
openapi-generator generate -i openapi.json -o ./src --generator-name typescript-fetch-hooks
or
openapi-generator generate -i openapi.json -o ./src --generator-name typescript-fetch -p useReactHooks=true
is inconsequential to me. I think there is a larger architectural decision to be made to determine which approach is "right" for open api in the long term
@abillingsley If I remember correct, core team members wants to stick to MVP(minimal valuable product) philosophy in this project. Satisfy TypeScript users and not provide a feature for javascript-client
is something that unlikely be done by core team. Of course you can create such generator for yourself and we'll probably merge your PR.
I work with frontend too(vanilla React). Current javascript-client
already contains superagent
package as http client. Maybe we should enhance javascript-client
as a start? If I don't miss something you can use ES6 javascript in TypeScript, right?
The important thing for any typescript developer would be to make sure type definitions exist and are correct. If the javascript-client
generator exports typescript type definitions then sure I would be willing to give it a try. If the choice were my own I'd prioritize typescript clients over javascript clients because you will satisfy typescript developers by providing accurate typescript types and javascript developers can benefit from the same code once it has been compiled with tsc. Effectively you could imagine a typescript-client
which depends on your same superagent
dependency. The javascript-client
could simply be the typescript-client
after it has been compiled
I agree with you @abillingsley.
~Btw is typescript-client
packed with superagent
too?~
Enhancement to javascript/typescript
client is interesting while typescript-react-hooks
independent generator without Models not so much. Or... if it contains Models then it's just an advanced typescript-client
with new feature, not a standalone codegen.
UPD: My bad, just noticed that there are typescript-axios
, typescript-fetch
etc. So there is no typescript client with superagent
http client.
I don't think there is a standalone typescript client. For typescript, I've only really seen typescript-fetch
and typescript-axios
I guess I am suggesting you could introduce a new generator for typescript which is dependant on superagent
just like the existing javascript-client
generator. Once that is done you could imagine a scenario where the implementation details of the javascript-client
generator simply become
typescript-client
doing so would allow open api to maintain a single generator that works for both typescript and javascript equally. The same strategy could be used for any of the javascript/typescript generators that may exist. I'd go further to suggest you may not even need to support javascript-*** generators at all since the typescript ones will just work for javascript developers too but for backward compatibility reasons, it probably makes sense to maintain the javascript generators you have.
I think we are starting to solve a different issue so to refocus on the original problem. If there is interest in perusing a reacts hooks api in either javascript or typescript I'd be willing to give it a try whether that comes as a standalone generator or a feature of an existing one. My personal bias would be towards providing Typescript types since I most often use Typescript
Thanks for the consideration
Also note that openapi-generator provides a mean for "light" customization via substituting built-in mustache templates with your own version (via --template-dir
).
Take, for instance, typescript-fetch
.
One could override apis.index.mustache to have smth like
import {makeReactHook} from "../your-custom-code/make-react-hook"
{{#operations}}
export * from './{{ classFilename }}';
export const {{classname}}Hook = makeReactHook({{classname}})
{{/operations}}
and implement this makeReactHook
in a way that suits your project
@amakhrov I am intrigued by your suggestion of overriding certain mustache templates. For your suggestion to work would I need to essentially fork the typescript-fetch
templates or is there support for using the default templates and include this extra behavior. While forking the generator is doable I'd like to avoid it if possible
I noticed the OpenAPI Roadmap includes "consolidate typescript generators". I also recently came across #802 which has some architectural discussion around the typescript generators. Perhaps including react hooks in that discussion is appropriate?
We are working on the generic typescript template. It is currently developed in its own branch. In it we have a framework
option. Currently we allow isomorphic-fetch
and jquery
as values. So it would be possible to add an option react-hooks
there.
Adding a new separate typescript-react-hooks template is a bad idea, imho, as it leads us further down into the maintenance hell.
I don't know how other people use the output of this generator or any generator in general. However In the projects that me and my team are involved in we always put an abstraction layer in between and never call the generated code directly from a component/controller/thunk/epic/effect or whatever. This way the application stays clean, isn't populated by any generated models or functions and therefore won't need tons of adjustments when the property of a model changes. Also frontend development isn't dependent on an API that isn't ready, yet. Instead we can work with mocked service calls until the API is done and then connect them later.
@denyo our team has worked both ways. Rarely if ever do we actually call generated code directly a react component. I'd say we are less worried about exposing OpenAPI models throughout the codebase since we often control the API and tend to have APIs return domain models anyway but the fact HTTP is used is more or less abstracted away.
Providing a custom hook does not preclude the use of additional abstraction layer(s) if that is desired. It can, however, reduce some boilerplate code that you might be otherwise writing.
I think the framework
option referenced above gives us a lot of options when it comes to the way applications will consume open api generated code.
If I am using thunks or sagas maybe I continue to generate code with isomorphic-fetch. But the application is lighter weight perhaps I go with the proposed react-hooks abstraction. In either case, I can still write additional code to abstract the open api models etc through the use of yet another custom hook or other strategies.
Adding a new separate typescript-react-hooks template is a bad idea, imho, as it leads us further down into the maintenance hell.
I realized recently that it was a main disadvantage of mysql
schema generator, now I think database schema decoupled from a server language makes no sense. I would add --storage=mysql
option to any server generator instead.
@amakhrov or @abillingsley Would using the --template-dir
option to override the apis.index.mustache
files be a good solution if we were hoping to use a 3rd party fetch hook like swr or react-query? Has anyone successfully done that and have an example project?
I'm in a similar scenario. I want to use TypeScript, Axios, and React Hooks together with an OpenAPI spec. I don't mind whether this is via a custom hook that uses the typescript-axios classes or via the useAxios hook (i.e. usePetApiFindPetsByStatus
would pass path, etc to useAxios
). But I do prefer to use axios and setup proper cancelation and error handling.
I tried following the documentation to override things and add an additional custom hooks.ts
with custom hooks that would use the generated classes. But it didn't work.
---
templateDir: generator
files:
hooks.mustache:
templateType: SupportingFiles
destinationFilename: hooks.ts
The API could look similar to what https://www.graphql-code-generator.com/ does
const { status, data, error } = usePetApiFindPetsByStatus();
const [{ status, data, error }, findPetsByStatus] = usePetApiFindPetsByStatusAsync();
I personally would like to see a React Query which is a hugely popular React library for querying and handling state. It is similar to what @simPod posted above syntax.
I personally would like to see a React Query which is a hugely popular React library for querying and handling state. It is similar to what @simPod posted above syntax.
There are dozens of tools. I used RTK Query
shipped with @reduxjs/toolkit
recently and really happy about it.
@ybelenko I understand that but what I am asking for is I have OpenAPI v3 JSON file I want to convert all of it to React Query and not native TypeScript Fetch and then have to wrap all my calls in React Query. I don't see how RTK Query is any different?
@ybelenko I understand that but what I am asking for is I have OpenAPI v3 JSON file I want to convert all of it to React Query and not native TypeScript Fetch and then have to wrap all my calls in React Query. I don't see how RTK Query is any different?
They got their own generator to convert openapi3 spec to RTK Query endpoints, 😆 . Another one. Didn't use it, since my spec was really small and I wrote all requests for an hour.
Ahh I have huge API's don't want my developers hand coding all these hooks. And I have been using this generator: https://orval.dev/ It does the job but its not as nice as openapi-generator
or as active
any updates?
Is your feature request related to a problem? Please describe.
I generally use openapi-generator with typescript-fetch in react applications. Which ends up looking something like or similar depending on the state management strategy being used.
The popularity of the react hooks api has to lead to the creation of libraries like react-query, axios-hooks and others.
Describe the solution you'd like
Similarly to how openapi-generator provides the option to generate
typescript-angular
,typescript-rxjs
, etc. it would be interesting to provide atypescript-react-hooks
to enable a number of the same api conveniences for the react ecosystem.I can imagine a similar api to one provided in libraries like
axios-hooks
orreact-query
where the response is a tuple is defined something like
Some of the challenges I acknowledge given the example api above would be the configuration of the underlying api class (eg
PetApi
). The typescript-fetch generated code provides substantial ability to customize fetch through the use of middlewares etc. Perhaps a React Context could assist with the configuration of the specific api classes?Describe alternatives you've considered
None, continue with the current strategy or write custom code to wrap open api generated code in hooks manually.
Additional context