Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Fix #4 by making API equal to graphqls #11

Merged
merged 7 commits into from
Jan 22, 2019
Merged

Conversation

DanielMSchmidt
Copy link
Contributor

Thank you @alexstrat for pointing this out. Would love to see a review from you if you have the time 👍

Daniel Schmidt added 5 commits January 21, 2019 16:55
BREAKING CHANGE: All imports need to be `import {graphql}` instead of
`import graphql` from now on

Closes #4
BREAKING CHANGE:  Its now schema, query instead of query, schema, so the
inputs in all projects need to change

Closes #4
@@ -359,7 +359,7 @@ function resolveField(
null // that would be the info
);

if (resolvedValue instanceof Observable) {
if (isObservable(resolvedValue)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd do the same treatment to Promise (L366) and use a isPromise like done in the reference implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't really see the benefit of duck typing instead of using instanceof, could you expand on your suggestion?

Copy link
Contributor

@alexstrat alexstrat Jan 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases, the user thinks they are returning a Promise but it's not treated as it by reactive-graphql. For instance, when the user uses a lib that leverages other implementation of Promise than a native one.

For example, Sequelize uses bluebird and returns instance of bluebird.Promise that will not be instanceof global.Promise.

As Promise became am es6 standard, this case have less and less chance to happen, but still.

However, it is even more true for Observable, as many implementations exist and cohabit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not aware that these implementations cohabit 🤔

@@ -67,12 +68,24 @@ function isFieldWithResolver(

export default function graphql<T = object>(
Copy link
Contributor

@alexstrat alexstrat Jan 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the reference implementation:

  • graphql high-level API accept both DocumentNode and String, and its implementation transform a string in a document before passing it to execute
  • execute accepts only DocumentNode and its implementation and its implementation is defined in an other file in execution folder

It could be an inspiration for renaming function, file and change function signatures.

Copy link
Contributor

@alexstrat alexstrat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 Thanks! Added few suggestions

README.md Outdated Show resolved Hide resolved
@@ -67,12 +68,24 @@ function isFieldWithResolver(

export default function graphql<T = object>(
schema: Schema,
Copy link
Contributor

@alexstrat alexstrat Jan 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphql(
  schema: GraphQLSchema,
  requestString: string,
  rootValue?: ?any,
  contextValue?: ?any,
  variableValues?: ?{[key: string]: any},
  operationName?: ?string
)

Actually, 3rd parameter is rootValue in the reference implementation. If you add support for rootValue in the future while keeping an API similar to the reference signature, the API will have to be broken. I think you should add unused rootValue parameter now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this makes sense, I'll try to add it in this PR 👍

alexstrat and others added 2 commits January 21, 2019 23:35
Co-Authored-By: DanielMSchmidt <[email protected]>
BREAKING CHANGE: Please add the root value as third argument, null or an
empty object are great default values for this.
@DanielMSchmidt
Copy link
Contributor Author

So, the root value is added, I'll merge this now, so we can get all of the great changes @alexstrat did out of the door quickly

@DanielMSchmidt DanielMSchmidt merged commit aa6aa0d into master Jan 22, 2019
@DanielMSchmidt DanielMSchmidt deleted the unify-inputs branch January 22, 2019 10:03
@mesosphere-frontend-ci
Copy link

🎉 This PR is included in version 3.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

rootValue?: any,
context: object = {},
variables: object = {}
): Observable<{ data?: T; errors?: string[] }> {
Copy link
Contributor

@alexstrat alexstrat Jan 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Observable<ExecutionResult<TData>>

// with:
export interface ExecutionResult<TData = ExecutionResultDataDefault> {
    errors?: ReadonlyArray<GraphQLError>;
    data?: TData;
}

Note the difference of type on the errors key, and indeed note that line 82, parse throwing GraphQLErrors, GraphQLErrors are pushed in errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that might have been a mistake, normally we throw the observable, we should do this here, too. I mean not being able to parse is a prime example for something that a client can not live without in contrast to errors in field resolvers where one could argue for partial delivery of the data tree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind fixing this into a throwObservable? I can do it tomorrow, but it would be nice to fix this even faster

Copy link
Contributor

@alexstrat alexstrat Jan 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given GQL spec, any request validation error should be reported in the list of “errors” in the response and the request must fail without execution.
I'm not sure if an error in the syntax should be understood as "validation error" and I'm not sure what "request fail" mean.

Anyway, in the reference implementation, they decided to add any SyntaxError to the list of errors and to resolve normally the result with the errors key.

Given this, while I understand your POV, I think that (appart the typing) the current implementation is correct and I'd let it as it. 🤷‍♂️

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok now I realize that every error is actually thrown away with the current implementation, so by consistency this one should the same. However, I think it would be more correct to aggregate errors in the errors array in the returned results => #13

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants