#node.js #typescript #graphql #typegraphql
#node.js #машинопись #graphql #typegraphql
Вопрос:
Я пишу распознаватель для извлечения данных из REST api в серверную функцию graphql с использованием typescript и type-graphql.Проблема, с которой я сталкиваюсь, заключается в том, что я получаю данные из API со всеми реквизитами, но я хочу возвращать только выбранные поля во внешнем интерфейсе. Как вернуть только выбранные поля?
Вот мой сценарий. У меня есть приложение react в качестве интерфейса. Я буду писать все запросы graphql в приложении fronetend. Во внешнем интерфейсе есть клиент apollo, который подключается к graphql в серверной части. Серверная часть — это приложение узла, написанное на машинописном языке. Мой серверный сервер извлекает данные из rest api и передает их во внешний интерфейс через сервер apollo. Мы используем type-graphql в серверной части
Здесь, в этом вопросе, у меня есть сомнения в отношении серверной части.
У меня есть следующий тип (определенный в серверной части как PersonInfo.ts)
import { ObjectType, Field } from "type-graphql";
@ObjectType("PersonInfo")
export class PersonInfo {
@Field({ nullable: true }) firstName: string;
@Field({ nullable: true }) lastName: string;
@Field({ nullable: true }) registrationNo: string;
@Field({ nullable: true }) personCode: string;
@Field({ nullable: true }) personCapabilities: string;
}
Я использую указанный выше тип в своем преобразователе, как показано ниже: (определено в серверной части как personInfoResolver.ts) Этот преобразователь graphql будет извлекать данные из rest api с помощью функции, написанной в следующей части. Эта функция имеет проблему, как указано в коде ниже.
import { Query, Resolver, Arg } from "type-graphql";
import { PersonInfo } from "../types";
import { GetPersonInfo } from "./api/helpers";
@Resolver((of) => PersonInfo)
export class PersonInfoResolver {
@Query((returns) => PersonInfo, { nullable: true })
async PersonInfo(@Arg("serialNo") serialNo: string) {
console.log(await GetPersonInfo(serialNo)); //<--this logs full object received from api with all the fields
return await GetPersonInfo(serialNo); //when queried from graphql playground, i get null for selected values even if previous line prints all data
}
}
Вот функция для получения данных в помощнике api (определенная в бэкэнде для подключения к api и получения данных.) Работает нормально и получает все объекты из rest api.
export const GetPersonInfo = async (serialNo: string) => {
var personInfoURL = "url" serialNo;
if (!serialNo) {
return "";
}
const response = await posApi
.get(personInfoURL)
.then(function (response) {
return response.data;
})
.catch(function (error) {});
const data = await response;
return data;
};
Я тестирую приведенный выше код с использованием graphql playground, используя следующий запрос.
{
PersonInfo(serialNo:"201123030"){
firstName
lastName
registrationNo
registrationNo
personCapabilities
}
}
Комментарии:
1. Этот вопрос неполный, где ваш graphql-запрос / мутация?
2. Или это то, что вам интересно? Как написать graphql-schema-функции?
3. Запрос @Joel будет находиться во внешнем интерфейсе приложения react. Прямо сейчас я пишу серверную часть в node и тестирую с использованием graphql play ground. Добавлен запрос, о котором идет речь
4. Я поддержу это за вас, это хороший вопрос, хотя и довольно запутанный. Пожалуйста, проверьте мой ответ ниже, он показывает вам, что вы хотите.
5. У вас была возможность взглянуть на мое решение?
Ответ №1:
Ваш вопрос мне неясен, но я постараюсь вам помочь.
Прежде всего, предоставленная вами схема GraphQL недействительна.
На игровой площадке вы должны написать:
{
PersonInfo(serialNo: "201123030") { //not DetailsInfo
firstName
...
}
}
Учитывая, что ваша сущность выглядит следующим образом:
@Column()
@Field({ nullable: true }) firstName: string;
@Column()
@Field({ nullable: true }) lastName: string;
@Column()
@Field({ nullable: true }) registrationNo: string;
@Column()
@Field({ nullable: true }) personCode: string;
@Column()
@Field({ nullable: true }) personCapabilities: string;
И что ваш распознаватель выглядит так:
@Resolver(PersonInfo)
export class PersonInfoResolver {
@Query(() => PersonInfo, { nullable: true })
async PersonInfo(@Arg("serialNo") serialNo: string): Promise<PersonInfo> {
return await GetPersonInfo(serialNo); //when queried from graphql playground, i get null for selected values even if previous line prints all data
}
}
Я рекомендую запустить
npm i -D @graphql-codegen @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/operations @graphql-codegen/typescript-react-apollo
что позволяет автоматически генерировать схемы и обеспечивать безопасность типов в вашем проекте.
Создайте файл, вызываемый codegen.yml
в вашем корневом каталоге вашего react-проекта (в том же месте, package.json
что и)
overwrite: true
schema: "http://localhost:4000/graphql"
documents: "src/graphql/**/*.graphql"
generates:
src/generated/graphql.tsx:
plugins:
- "typescript"
- "typescript-operations"
Создайте папку generated
src/*
в.
ИЛИ измените структуру выше на то, где вы хотите, чтобы схемы были сгенерированы.
Сначала вам нужно создать personinfo.query.graphql
в src/graphql/queries/*
(Вы также можете создать другую папку, вызываемую src/graphql/mutations/
здесь)
personinfo.query.graphql
query PersonInfo($serialNo: String!) {
personInfo(serialNo: $serialNo) {
firstName,
lastName,
registrationNo,
personCode,
personCapabilities //or whatever subset of fields you want.
}
}
В вашей консоли введите: graphql-codegen --config codegen.yml
и файлы будут сгенерированы. Откройте graphql.tsx
сейчас и посмотрите, что он создал. Довольно аккуратно, не так ли?
Затем в вашем реагирующем компоненте просто сделайте:
export const MyComponent: React.FC<{}> = ({}) => {
const [{data}] = usePersonInfoQuery({/*your serialNo here*/}); //this function will have been generated now
//then you have access to the fields you supplied to `personinfo.query.graphql`
const fName = data.personInfo.firstName;
const lName = data.personInfo.lastName;
}
Комментарии:
1. detailsinfo — это просто ошибка копирования вставки. Это было ранее detailsinfo. Обновлено в вопросе. Также добавлена дополнительная информация о контексте.
2. @GauravChauhan Пожалуйста, проверьте мое решение, оно показывает вам, как выбрать подмножество полей в вашем интерфейсе с помощью apollo.