0

I have a server side schema with this mutation type

type Mutation {
  updateSettings(settings: SettingsInput): Settings
}
input SettingsInput {
  repositories: [RepositoryInput]
}
input RepositoryInput {
  id: String
  name: String
  url: String
}

I can mutate this exactly like I want to if I use a client such as Altair, with this query:

mutation{
  updateSettings(settings: {
    repositories: [
      {
         name: "name1"
         url: "url1"
      },
      {
         name: "name2"
         url: "url2"
      }
    ]
  }){
    repositories {
      id
      name
      url
    }
  }
}

However I am struggling to get it working when using Apollo

The best I can get is this

import { SubscriptionClient } from "subscriptions-transport-ws";
import { gql } from "apollo-boost";
import { WebSocketLink } from "apollo-link-ws";

const wsClient = new SubscriptionClient("ws://localhost:5001/graphql", {
  reconnect: true
});
const client = new WebSocketLink(wsClient);
const UPDATE_SETTINGS = gql`
  mutation UpdateSettings($settings: SettingsInput) {
    updateSettings(settings: $settings) {
      repositories {
        id
        name
        url
      }
    }
  }
`;
client
      .request({
        query: UPDATE_SETTINGS,
        variables: { repository: [{name: "name1", url:"url1"},
                                  {name: "name2", url:"url2"}]}
      })

I am obviously missing something. The client doesn't seem to be aware of the servers SettingsInput, but I can't really figure out how to create a query for the client that takes complex objects or arrays as variables.

Am I going about this in a totaly weird way or how do I go about sending "complex" mutations to the server from an apollo client?

munHunger
  • 2,572
  • 5
  • 34
  • 63
  • `subscriptions-transport-ws` is used for subscriptions. It's not an appropriate transport for queries and mutations. It's not really clear why you're using that instead of `apollo-client` or `apollo-boost`. – Daniel Rearden Sep 09 '19 at 18:29
  • Mainly because I thought of it as a cleaner way to send data only through one client. I am on the side of this also using subscriptions and queries over that same client – munHunger Sep 09 '19 at 18:53
  • While it may be technically possible to implement queries and mutations over WebSockets, pretty much all server-side libraries that expose a GraphQL service as an endpoint (for example, Apollo Server) only support receiving queries and mutations via POST/GET requests. Using WebSockets as a transport for these operations would require considerable work on both the front-end and backend. – Daniel Rearden Sep 09 '19 at 19:11
  • You should [migrate from apollo-boost to apollo-client](https://www.apollographql.com/docs/react/v2.5/advanced/boost-migration) and then implement subscription support as shown [here](https://www.apollographql.com/docs/react/v2.5/advanced/subscriptions/#client-setup). – Daniel Rearden Sep 09 '19 at 19:14
  • alright, fair and valid point. however, it looks like apollo-client follows the same client query structure, so I would probably be equally confused as to how to define a list of objects as a variable to the query. But am I wrong and is this in any way handled differently? – munHunger Sep 09 '19 at 19:20

1 Answers1

1

The client aside, you also need to fix the variables object you're passing in. The variable you've defined in your operation is named settings, but you are only passing in a variable named repository. Additionally, the shape of this variable doesn't match SettingsInput as shown in your schema. variables should look something like:

const variables = {
  settings: {
    repositories: [
      {
        name: 'name1',
        url: 'url1'
      },
      {
        name: 'name2',
        url: 'url2'
      },
    ],
  },
}
Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183