RootQuery Resolve: вызывает сервис в отдельном js-файле - PullRequest
0 голосов
/ 25 января 2019

Я в порядке с JavaScript, но я очень плохо знаком с GraphQL.В настоящее время у меня есть эта структура GraphQL, и она работает.В Интернете я нашел примеры того, как организовать различные типы файлов SRP.Однако я не могу найти, как это сделать с помощью разрешения: так как для этого требуется функция.

GraphQL:

const RootQueryType = new GraphQLObjectType({
   name: 'RootQueryType',

   fields: {

    ownerData: {
        type: OwnerType,
        description: 'Get all owners',
        args:{key: {type: GraphQLString} },
        resolve: (obj, args) => {
            const url = 'http://localhost:5001/api/.../' + args.key
            return fetch(url)
                .then(response => {
                    return response.json()
                })
                .then(json => {
                    return transform(json)
                })
                .catch(err => {
                    console.trace(err)
                })
        }
    },
    carData: {
        type: carType,
        description: 'Get owned vehicles',
        args:{key: {type: GraphQLString} },
        resolve: (obj, args) => {
            const url = 'http://localhost:6001/api/.../' + args.key
            return fetch(url)
            .then(response => {
                return response.json()
            })
            .then(json => {
                return transform(json)
            })
            .catch(err => {
                console.trace(err)
            })  
        }
    },
}
})

Я могу переместить вызовы службы в отдельные файлы, но не уверен, какструктурировать решение так, как ему нужна функция.

Было бы что-то вроде этого:

const VehicleService = require('./ExternalServices/Vehicles');
.....snip...
resolve: (obj, args) => { VehicleService.GetVehicles() }

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Вообще говоря, я обнаружил, что лучший способ сохранить мой код организованным - это поместить всю бизнес-логику в другое место, инициализировать в объект context. Если вы используете graphql-js напрямую (он будет настроен иначе, если вы используете что-то вроде apollo-server, но context все еще подходит для этого):

выдержка из graphql.js (загрузчики данных - это логика SRP)

const { graphql } = require('graphql');
const dataloaders = require('./dataloaders');
const typeDefs = require('./type-definitions')
const schema = require('./schema')

exports.query = (whatever, args) => {
  const context = {};
  context.requestId = 'uuid-something';
  context.loaders = dataloaders.initialize({ context });

  return graphql(schema, query, null, context)
}

схема.js выдержка

const RootQueryType = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    ownerData: {
      type: OwnerType,
      description: 'Get all owners',
      args:{key: {type: GraphQLString} },
      resolve: (obj, args, context) => {
        const key = args.key;
        return context.loaders.owner({ key });
      }
    }
  }
});

выдержка dataloaders.js

exports.initialize = ({ context }) => {
  return {
    owner({ key }) {
      const url = 'http://localhost:6001/api/.../' + key
      return fetch(url, { headers: { requestId: context.requestId }})
        .then(response => {
          return response.json()
        })
        .then(json => {
          return transform(json)
        })
        .catch(err => {
          console.trace(err)
        });
    }
  }
};

В дополнение к лучшей организации кода, выполнение этого способа позволяет упростить тестирование, поскольку ваши распознаватели не нуждаются во внешних зависимостях. Таким способом вы можете внедрить свои зависимости, предварительно загрузив контекст тем, что вы хотите для тестирования, и вы можете обрабатывать бизнес-логику, к которой относится бизнес-логика.

Инициализация вашей бизнес-логики с контекстом запроса также позволяет вам настраивать функциональность на основе запроса: requestId (как я показал), контроль доступа и т. Д.

0 голосов
/ 25 января 2019

Синтаксис () => {} - это просто определение функции.Поле resolve ожидает определения функции, поэтому оно может запустить его, когда поле должно быть разрешено.
Вы можете переместить функцию разрешения в другой файл, например, так:
car-data-resol.js:

const resolveCarData = (obj, args) => {
  const url = 'http://localhost:6001/api/.../' + args.key
  return fetch(url)
  .then(response => {
    return response.json()
  })
  .then(json => {
    return transform(json)
  })
  .catch(err => {
    console.trace(err)
  })  
}
export default resolveCarData;

А затем используйте его в определении схемы:

import resolveCarData from './car-data-resolve';

const RootQueryType = new GraphQLObjectType({
    name: 'RootQueryType',

    fields: {
        /* Other fields */
        carData: {
            type: carType,
            description: 'Get owned vehicles',
            args: { key: { type: GraphQLString } },
            resolve: resolveCarData
        },
    },
});

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...