Skip to content
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

Merging schemas that use apollo-upload-server #671

Closed
rohit-ravikoti opened this issue Mar 9, 2018 · 17 comments
Closed

Merging schemas that use apollo-upload-server #671

rohit-ravikoti opened this issue Mar 9, 2018 · 17 comments
Labels
blocking Prevents production or dev due to perf, bug, build error, etc.. feature New addition or enhancement to existing solutions has-reproduction ❤ Has a reproduction in a codesandbox or single minimal repository schema stitching v5

Comments

@rohit-ravikoti
Copy link

rohit-ravikoti commented Mar 9, 2018

Hello,
Is there any way to merge schemas that use apollo-upload-server? Here is a contrived example:

import { GraphQLServer } from 'graphql-yoga'
import {
  mergeSchemas,
  makeExecutableSchema,
} from 'graphql-tools';

const UploadScalar = makeExecutableSchema({
  typeDefs: `
    scalar Upload
    type Query {
      _uploadTest: Boolean
    }
    type Mutation {
      _uploadTest: Boolean
      updateProfilePicture(
        picture: Upload!
      ): Boolean
    }
  `,
  resolvers: {
    Mutation: {
      updateProfilePicture(_, args) {
        console.log(args)
        return {
          success: true
        }
      }
    }
  }
})
  const server = new GraphQLServer({
    schema: mergeSchemas({
      schemas: [UploadScalar]
    })
  })
  server.start({
    port: 5444
  }, () => console.log('Server is running on http://localhost:5444'))

Basically, the Upload does not get forwarded to the schema and resolvers. I just get an empty picture object from the args.

If I use UploadScalar directly for the schema (const server = new GraphQLServer({ schema: UploadScalar })), it works. Of course, I don't do this in a real-world scenario. I would be merging multiple remote schemas which may use apollo-upload-server.

Does anyone know of a way I could work around this?

@ghost ghost added feature New addition or enhancement to existing solutions has-reproduction ❤ Has a reproduction in a codesandbox or single minimal repository blocking Prevents production or dev due to perf, bug, build error, etc.. labels Mar 9, 2018
@medeeiros
Copy link

This issue blocks us from using mergeSchemas / schema-stitching.
Can somebody point out where this needs to be fixed? I'm happy to contribute.

@marhub
Copy link

marhub commented Aug 31, 2018

@GuilhermeMedeiros @rohit-ravikoti have you managed to resolve this ? I have stumbled uppon same issue...

@medeeiros
Copy link

@marhub I had to implement apollo-client on the server that does the stitching. Please check jaydenseric/graphql-upload#56

@jaydenseric
Copy link

A side-note for those unfamiliar with the change, but apollo-upload-server has been republished as graphql-upload (see jaydenseric/graphql-upload#68).

@plmercereau
Copy link

Hello,
Does the Apollo team plan to implement this feature soon? I am totally stuck and would like to know if and when the magic could happen...

@pozylon
Copy link
Contributor

pozylon commented Mar 12, 2019

This is also blocking me, I have to bypass the gateway until this works. This guy has implemented some kind of workaround into apollo-upload-client and describes the process in the readme of the PR: jaydenseric/apollo-upload-client#79

Sadly the author closed the PR but @jaydenseric left an idea there, mentioning that extract-files could be patched allowing streams. Workaround partial: https://github.com/jaydenseric/apollo-upload-client/pull/79/files#diff-0730bb7c2e8f9ea2438b52e419dd86c9

@MichelMelhem
Copy link

+1

@yaacovCR
Copy link
Collaborator

yaacovCR commented Dec 31, 2019

graphql-tools-fork v8.1.0 provides support for proxying remote file uploads for those who want to proxy all the things.

The new createServerHttpLink method should be used to set up a terminating link to a subschema; it will resolve all promises within the variables, and then, if appropriate, append the File or stream to the FormData.

The GraphQLUpload scalar export from graphql-tools-fork is a one-line code change from the original from the graphql-upload package that allows use on the gateway.

Feedback/critiques/suggestions would be much appreciated. I am happy to submit PRs where appropriate, this is more POC.

Please join in further discussion at: jaydenseric/apollo-upload-client#172 (comment)

@kamilkisiela
Copy link
Collaborator

We recently released an alpha version of GraphQL Tools (#1308) that should fix the issue.

Please update graphql-tools to next or run:

npx match-version graphql-tools next

Let us know if it solves the problem, we're counting for your feedback! :)

@yaacovCR yaacovCR mentioned this issue Mar 27, 2020
22 tasks
@yaacovCR
Copy link
Collaborator

Rolled into #1306

maasencioh added a commit to maasencioh/apollo-server that referenced this issue Jul 1, 2020
I assume that how that the issue is closed this comment should be removed

ardatan/graphql-tools#671
@alesso-x
Copy link

alesso-x commented Apr 8, 2021

This is the first result on google and it's not super clear on how to fix the issue or why this happens. TL;DR change the import of GraphQLUpload.

Also see #2795 (comment) and jaydenseric/graphql-upload#194 about the reason why this throws an error.

const { makeExecutableSchema } = require('graphql-tools');
- const { GraphQLUpload } = require('graphql-upload');
+ const { GraphQLUpload } = require('@graphql-tools/links');

const schema = makeExecutableSchema({
  typeDefs: /* GraphQL */ `
    scalar Upload
  `,
  resolvers: {
    Upload: GraphQLUpload,
  },
});

@yaacovCR
Copy link
Collaborator

yaacovCR commented Apr 9, 2021

Actually, the subschema can use the original scalar. The gateway schema needs to use the modified scalar. See fully worked example at https://github.com/ardatan/graphql-tools/blob/20a066e17669f66324486e978ac66c8f1c6ce100/packages/links/tests/upload.test.ts

@alesso-x
Copy link

alesso-x commented Apr 9, 2021

@yaacovCR thank you for the clarification. Updated code snippet below.

// schema.js
const { makeExecutableSchema } = require('graphql-tools');
const { GraphQLUpload } = require('graphql-upload');

const schema = makeExecutableSchema({
  typeDefs: /* GraphQL */ `
    scalar Upload
  `,
  resolvers: {
    Upload: GraphQLUpload,
  },
});

// makeGatewaySchema.js
import { stitchSchemas } from "@graphql-tools/stitch";
import { GraphQLUpload as ServerGraphQLUpload } from "@graphql-tools/links";

const gatewaySchema = stitchSchemas({
  subschemas: [schema],
  resolvers: {
     /* ADD THIS */
    Upload: ServerGraphQLUpload,
  },
});

@yaacovCR
Copy link
Collaborator

yaacovCR commented Apr 9, 2021

Minor nit with my test code, term ServerGraphQLUpload is silly, these two schemas should be living on two different servers, so that both or neither should be called that. When I have time, I should change to GatewayGraphQLUpload.

The name came from the fact that it is being used together with a server side HttpLink

@alesso-x
Copy link

alesso-x commented Apr 9, 2021

@yaacovCR I thought my previous comment 2 worked but it's actually throwing an error. My first attempt does work comment 1.

My setup: I have one local schema that includes Upload and one remote schema that does not use Upload. As in my previous comment 2 I added the resolver from graphql-tools to stitchSchemas and kept the import of GraphQLUpload from graphql-upload in the schema. I received an error from graphql-upload/.../GraphQLUpload.js#L82

{
  "message": "Variable \"$file\" got invalid value {}; Expected type Upload. Upload value invalid.",
  "locations": [{ "line": 6, "column": 3 }],
  "path": ["createMessage"],
  "extensions": {
    "code": "INTERNAL_SERVER_ERROR",
    "exception": {
      "message": "Upload value invalid.",
      "stacktrace": [
        "GraphQLError: Upload value invalid.",
        "    at GraphQLScalarType.parseValue (/data/node_modules/graphql-upload/public/GraphQLUpload.js:82:11)",
        "    at coerceInputValueImpl (/data/node_modules/graphql/utilities/coerceInputValue.js:127:26)",
        "    at coerceInputValueImpl (/data/node_modules/graphql/utilities/coerceInputValue.js:54:14)",
        "    at coerceInputValue (/data/node_modules/graphql/utilities/coerceInputValue.js:37:10)",
        "    at _loop (/data/node_modules/graphql/execution/values.js:107:69)",
        "    at coerceVariableValues (/data/node_modules/graphql/execution/values.js:119:16)",
        "    at getVariableValues (/data/node_modules/graphql/execution/values.js:48:19)",
        "    at buildExecutionContext (/data/node_modules/graphql/execution/execute.js:184:61)",
        "    at executeImpl (/data/node_modules/graphql/execution/execute.js:89:20)",
        "    at Object.execute (/data/node_modules/graphql/execution/execute.js:64:35)"
      ]
    }
  },
  "level": "error",
  "timestamp": "2021-04-09T16:14:48.813Z"
}

@yaacovCR
Copy link
Collaborator

Can’t really say, linked test code seems pretty similar to your setup from your description, consider putting together a PR with a failing test off of that and we can try to see what we can see

@alesso-x
Copy link

alesso-x commented May 31, 2021

@yaacovCR I made a PR gmac/schema-stitching-handbook#30 to the schema stitching handbook to reproduce the error. I copied the example combining-local-and-remote-schemas and added graphql-upload. I also simplified the example to only include one remote schema and one local schema.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocking Prevents production or dev due to perf, bug, build error, etc.. feature New addition or enhancement to existing solutions has-reproduction ❤ Has a reproduction in a codesandbox or single minimal repository schema stitching v5
Projects
None yet
Development

No branches or pull requests