-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
to wrap or not to wrap? #63
Comments
This would be a nice scenario // get the service from somewhere... container, global, singleton, factory, blah
var myService = getMyServiceInstance();
// make the request, it will return a promise
var response = myService.getPost(15).then((response) => {
// Handle error scenarios
if (!response.ok || !response.hasData) {
handleMyErrorStuff();
}
// Handle success scenario
alert(`the cow say ${response.data.value}`);
}); |
IMO, just use the promise returned by fetch. And maybe add a middleware or something which will modify the fetch data. Maybe someone will look for something to do with those native fetch promises. |
yes totally doable. Middleware should be the way to go. Though we would have to loosen typing on Stack as this will introduce type changes |
Very basic ideas for wrapping: interface IServiceRequestIncludes everything needed to be converted to a FetchRequest. Provides a nested FetchOptions as well. class ServiceResponse
class ServiceMiddlewareSits on top of the FetchStack. Is added to Stack in Service-class.
ServiceHas a configured client instance. Offers a request-method which accepts a IServiceRequest (for codecompletion) |
My suggestion: include a wrap middleware which simply does a json, and returns a wrapped response, with a key of "body", that way user will still be able to access status code, headers (if any) etc. When a consumer decides to use this, their SDK will also need to do the typing accordingly. cc @paibamboo Doesn't include any more complexity, uses just plain middleware. If only we could provide a documentation on how to use it (with generics), so user has ability to use both wrap and without wrap on same generated SDK (generics should be able to solve this) |
Actually I just changed my mind on that, I think we should allow 3 ways,
BUT not all 3 in one (that'd pollute the code), so here's my proposal: include a wrapp middleware which can do
(can be 2 separate middlewares) One downside is that it'll increase a lot of typings: Here's what it'd look like (interfaces will need to be generated for all 3 types) (generator can decide not to do all 3 and just 1 as well) interface IWrappedUserNode {
findById(id: number): Promise<Wrapped<User>>
}
interface IUserNode {
findById(id: number): Promise<User>
}
interface IRawUserNode {
findById(id: number): Promise<IFetchResponse<User>>
} Then each node would look like this (but this won't need to be duplicated)class UserNode implements IUserNode, IWrappedUserNode, IRawUserNode {
public findById(id: number): Promise<any> {
return Promise.resolve() as any;
}
} finally Sdk would look like this:class SdkWrapped extends Service {
public get user(): IWrappedUserNode {
return new UserNode(this.client);
}
}
class Sdk extends Service {
public get user(): IUserNode {
return new UserNode(this.client);
}
}
class SdkRaw extends Service {
public get user(): IRawUserNode {
return new UserNode(this.client);
}
} Again, the generator can actually do either of these, Another option is to let generator decide if it even wants this middleware (or if it wants, then maybe even let them implement as well, which means it won't have to be in this repo and issue could be closed), I'm fine either way, please express your thoughts. cc @paibamboo @wmathes |
Now that the module structure is finally working like a charm, i'm playing around with actually using this with the shop service module. Having the native fetch response with typing still feels very clunky and i'm thinking about if we should wrap it or not...
Here's a quick example to illustrate the idea and the problem.
Creating a service package will basically consist of a class which extends Service like so
So this is nice and fine. Easy to read and generate. It will pass through the Stack, reach the Fetch Middleware and return Promise containing the typed FetchResponse. All good?
Not quite... because of the nature of the fetch response object which needs a lot of caretaking to play nicely... like so
This looks ok on a first glance, but feels kind of clunky and i can already feel the pain of having to write this code block hundreds of times. Sadly there are some good reasons behind it.
Pros
Cons
So how can we solve this without loosing some of the benefits of this approach?
Initially we had the FetchResponse class to handle parsing of the FetchResponse and i think we should go for this again. There should be some changes made though, which may require a few changes to the Client class (mostly to it's typings).
request? response?
data, text, blob?
hasData, hasText, hasBlob?
ok, status, statusText?
headers?
any additional fields?
How to handle middleware adding additional values to the request?
The text was updated successfully, but these errors were encountered: