RESTyped: End-To-end Typing for REST APIs with TypeScript
blog.falcross.com
blog.falcross.com
I use swashbuckle to automatically generate swagger https://www.nuget.org/packages/Swashbuckle/
Then paste swagger definition into the online editor to generate TypeScript client: https://swagger.io/swagger-editor/
(You can also generate offline).
How is RESTyped better than Swagger Codgen?
RESTyped has a couple of advantages over this:
- RESTyped definitions are extremely lightweight and don't require shipping an API wrapper with a bunch of generated code
- No build/manual copy step required. Easy to distribute typings on NPM.
- In what way are RESTyped definitions lighter? A Swagger definition is just a JSON or YAML file and can be used without shipping any additional code (e.g. by https://github.com/swagger-api/swagger-js).
- Swagger only requires a build step when the definition is used to generate code. Definitions can be distributed via NPM (e.g. https://www.npmjs.com/package/appveyor-swagger).
Edit: I realized you were talking about RESTyped being lighter/nobuild compared to Swagger Codegen specifically for TypeScript because it is written in TypeScript. Seems reasonable.
I wish XML-RPC hadn't ruined things so utterly, so we could properly refer to these APIs as JSON-RPC and leave REST for hypertext-based architectures (e.g. intercooler.js + html)
This project looks very promising for building full-stack apps spanning Node and the browser. One thing I would love to see eventually is a reduction in the need for manually pulling attributes from the request body and parsing query params. Does this provide a foundation for building a frictionless end-to-end experience via data adapters (which have served me well in Django/Ember projects, despite some mismatches)?
Maybe there are also some situations where GraphQL fails, I would definitely be interested to hear about that.
It seems to me that all of GraphQL's type information should be easier to use in Typescript.
I have noticed there is a compiler of .graphql files to .d.ts files [1], and I could see using something like that the way that RESTyped is used in the article here (though it's "backwards" from the RESTyped model where the Typescript definitions are the source of truth [2]), but at least in examples I've seen to date of GraphQL in the wild it does seem like there is a similar need in the GraphQL world for something like RESTyped.
[1] https://www.npmjs.com/package/graphql-typescript-definitions
[2] Which leads me to wondering if it would be nice to have a Typescript Definition file to GraphQL compiler.
I wrote an article about using apollo-codegen to generate all the Typescript types:
https://medium.com/@crucialfelix/bridging-the-server-client-...
It's still a few steps too many, but it's getting there.
I'm about to write up the second article which deals with mutations. This lets me import only one type:
import { SetAptListOnWebProps } from "../mutations";
and then this.props.mutate is fully typed: (property) mutate: (options: MutationOptions<{
apt: string;
listOnWeb: boolean;
}, {
setAptListOnWeb: {
apt: {
id: string;
listOnWeb: boolean;
__typename: "Apt";
};
__typename: "SetAptListOnWebPayload";
};
}>) => Promise<{
data: {
setAptListOnWeb: {
apt: {
id: string;
listOnWeb: boolean;
__typename: "Apt";
};
__typename: "SetAptListOnWebPayload";
};
};
errors?: GraphQLError[];
loading: boolean;
networkStatus: NetworkStatus;
stale: boolean;
}>
First type argument is the mutation input variables, the optional second is the shape of the optimistic response.Relay Modern's query compiler also generates Flow types AFAIK.
But that's only for the client side. I suppose if you'd like to use typed JavaScript on the server side, something like the library you've posted might be your best bet, since client side solutions like apollo-codegen generate types based on the exact set of queries in your client-side app, which might not be all that useful for implementing the GraphQL server itself (unless maybe your API is private and you can afford to implement some form of persisted queries?). Having access to all the individual base types specified in your schema would probably be more useful for that purpose.
I know one, but it will take you a while to realize it. Allowing a lot of flexibility in query types makes it harder to optimize later when you can't predict the code paths your clients will take. In the API world, I have learned the hard way that flexibility is a bad thing especially compared to specific ways to obtain data and very optimizable, well-known "hot" paths to data.
If anything, a GraphQL server can still be used in a RESTful manner (perform a pre-written query, get its results) so there's a lot of pros (with very, if any, cons) with using a GraphQL server.
We're a strong believer in TypeScript which we've configured in all our .NET Core 2.0 / .NET Framework Single Page App project templates:
http://docs.servicestack.net/releases/v5.0.0#new-net-core-20...
I usually shared types from the backend to the front end in the same repo. Then change
(data: any)
To something like (data: User)
See this repoMaybe old dogs did understand a few things about doing distributed programming.
Got a link to the thread?
The types are defined, so no need for documentation to explain the semantics. Oh, and if you don’t have the same tool stack, good luck getting the envelope header the way our server wants it.
Sometimes, there’s value in being able to add or omit attributes without some brittle (static) monstrosity messing itself.