GraphQL突变,在一个请求中接受动态大小和常见标量类型的数组

oct*_*ron 15 javascript graphql apollostack

我需要能够在一个请求中创建一个用户并添加它最喜欢的电影(一组参与电影收藏的对象及其对每部电影的个人评级).

可能看起来像这样的东西(伪代码)

var exSchema = `
 type Mutation {
    addUser(
        name: String!
        favMovies: [{ movie: String! #ref to movies coll
                      personal_rating: Int! # this is different for every movie
                   }]
    ) : User
 }
...
`
Run Code Online (Sandbox Code Playgroud)

在单个请求中执行此操作的graphql方式是什么?我知道我可以通过多个突变/请求来实现结果,但我想在一个突发/请求中完成.

oct*_*ron 28

你可以传递这样的数组

var MovieSchema = `
  type Movie {
   name: String
  }
  input MovieInput {
   name: String
  }
  mutation {
   addMovies(movies: [MovieInput]): [Movie]
  }
`
Run Code Online (Sandbox Code Playgroud)

然后在你的变异中,你可以传递一个数组

mutation {
  addMovies(movies: [{name: 'name1'}, {name: 'name2'}]) {
    name
  }
}
Run Code Online (Sandbox Code Playgroud)

没有测试过代码,但你明白了

  • 这将是如此酷,但我将`movies:String`更改为`movies:[MovieInput]`graphql throws*错误:预期的输入类型.*当然在此之前我已经声明了`Type MovieInput` (2认同)

Cor*_*usK 5

我最终手动解析了正确的模式,因为 JavaScript 数组和 JSON.stringify 字符串不被接受为 graphQL 模式格式。

const id = 5;
const title = 'Title test';

let formattedAttachments = '';
attachments.map(attachment => {
  formattedAttachments += `{ id: ${attachment.id}, short_id: "${attachment.shortid}" }`;      
  // { id: 1, short_id: "abcxyz" }{ id: 2, short_id: "bcdqrs" }
});

// Query
const query = `
  mutation {
    addChallengeReply(
      challengeId: ${id}, 
      title: "${title}", 
      attachments: [${formattedAttachments}]
    ) {
      id
      title
      description
    }
  }
`;
Run Code Online (Sandbox Code Playgroud)

  • 这救了我的命。非常感谢您的片段 (2认同)

Ula*_*Ula 5

我想出了一个简单的解决方案-不使用JSON。仅使用一个输入。希望它会帮助别人。

我必须添加此类型:

type Option {
    id: ID!
    status: String!
    products: [Product!]!
}
Run Code Online (Sandbox Code Playgroud)

我们可以添加突变类型并添加输入,如下所示:

type Mutation {
    createOption(data: [createProductInput!]!): Option!
    // other mutation definitions
}

input createProductInput {
    id: ID!
    name: String!
    price: Float!
    producer: ID!
    status: String
}
Run Code Online (Sandbox Code Playgroud)

然后可以使用以下解析器:

const resolvers = {
    Mutation: {
      createOption(parent, args, ctx, info) {

        const status = args.data[0].status;

        // Below code removes 'status' from all array items not to pollute DB.
        // if you query for 'status' after adding option 'null' will be shown. 
        // But 'status': null should not be added to DB. See result of log below.
        args.data.forEach((item) => {
            delete item.status
        });

        console.log('args.data - ', args.data);

        const option = {
            id: uuidv4(),
            status: status,  // or if using babel    status,
            products: args.data
        }

        options.push(option)

        return option
      },
    // other mutation resolvers
    }
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用它添加一个选项(STATUS是从数组的第一项中获取的-它可以为空):

mutation{
  createOption(data:
    [{
            id: "prodB",
            name: "componentB",
            price: 20,
            producer: "e4",
            status: "CANCELLED"
        },
        {
            id: "prodD",
            name: "componentD",
            price: 15,
            producer: "e5"
        }
    ]
  ) {
    id
    status
    products{
      name
      price
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

产生:

{
  "data": {
    "createOption": {
      "id": "d12ef60f-21a8-41f3-825d-5762630acdb4",
      "status": "CANCELLED",
      "products": [
        {
          "name": "componentB",
          "price": 20,
        },
        {
          "name": "componentD",
          "price": 15,
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

无需说要获得以上结果,您需要添加:

type Query {
    products(query: String): [Product!]!
    // others
}

type Product {
    id: ID!
    name: String!
    price: Float!
    producer: Company!
    status: String
}
Run Code Online (Sandbox Code Playgroud)

我知道这不是最好的方法,但是我没有在文档中找到这样做的方法。