parse-server icon indicating copy to clipboard operation
parse-server copied to clipboard

GQL format array results into elements from cloud functions

Open axelhildingson opened this issue 4 years ago • 3 comments
trafficstars

New Pull Request Checklist

  • [] I am not disclosing a vulnerability.
  • [X] I am creating this PR in reference to an issue.

Issue Description

Parse does not convert arrays into arrays of elements for cloud functions.

TODO: We could perhaps adopt the relay, node edges architecture on cloud functions that return arrays of parse objects.

Related issue: https://github.com/parse-community/parse-server/issues/7197

Approach

The initial commit just contains an example that shows the error. I need help to find the solution to the issue.

TODOs before merging

  • [X] Add test cases
  • [ ] Add entry to changelog
  • [ ] Add changes to documentation (guides, repository pages, in-code descriptions)
  • [ ] Add security check
  • [ ] Add new Parse Error codes to Parse JS SDK
  • [ ] ...

axelhildingson avatar Aug 21 '21 08:08 axelhildingson

Thanks for opening this PR!

What kind of help do you need to find a solution? What is the step you are stuck at?

mtrezza avatar Aug 21 '21 10:08 mtrezza

I can see that we resolve the cloud functions in schemaDirectives and the normal query in parseClassQueries. The result of the resolver is basically the same, just a vanilla object. But I can't find where the result is transformed to gql types.

I have seen that we run defaultGraphQLTypes.loadArrayResult(this, parseClasses);, it seems that this doesn't affect the cloud functions.

It would be nice if we transform arrays of class objects into nodes and edges for cloud functions as well. That is more of a proposal rather than an issue 😃.

axelhildingson avatar Aug 21 '21 11:08 axelhildingson

Hi @axelhildingson

it seems that everything works correctly with the last version of Parse Server.

The following test actually pass 🚀

      fit('can resolve a custom query, that returns an array', async () => {
        const schemaController = await parseServer.config.databaseController.loadSchema();

        await schemaController.addClassIfNotExists('SuperCar', {
          engine: { type: 'String' },
          doors: { type: 'Number' },
          price: { type: 'String' },
          mileage: { type: 'Number' },
          gears: { type: 'Array' },
        });

        await new Parse.Object('SuperCar').save({
          engine: 'petrol',
          doors: 3,
          price: '£7500',
          mileage: 0,
          gears: ['1', '2', '3', '4'],
        });

        await new Parse.Object('SuperCar').save({
          engine: 'petrol',
          doors: 3,
          price: '£7500',
          mileage: 10000,
          gears: ['1', '2', '3', '4', '5'],
        });

        await Promise.all([
          parseGraphQLServer.parseGraphQLController.cacheController.graphQL.clear(),
          parseGraphQLServer.parseGraphQLSchema.schemaCache.clear(),
        ]);

        Parse.Cloud.define('arrayOfSuperCar', async () => {
          const superCars = await new Parse.Query('SuperCar').find({ useMasterKey: true });
          return superCars;
        });
        const result = await apolloClient.query({
          query: gql`
            query FindSuperCar {
              arrayOfSuperCar {
                objectId
                gears {
                  ... on Element {
                    value
                  }
                }
              }
            }
          `,
        });
        expect(result.data.arrayOfSuperCar[0].gears[2].value).toEqual('3');
      });

On your provided test, the "expect" was not correct. Please could you adjust your test to correctly reproduce the original issue, if it still exists 🙂

Moumouls avatar Jun 12 '22 19:06 Moumouls