Обобщение на нови функции, корекции на грешки и критични промени

Вчера беше пусната версия 0.7 на GraphQL.js и съдържа много вълнуващи подобрения, включително нови функции за езика на схемата, актуализация на функциите за разрешаване по подразбиране и помощни програми за конструиране и обработка на GraphQL документи. В тази публикация ще разгледам:

  • Нови функции - как, кога и защо да ги използвате
  • Разрушителни промени – как и дали ви влияят
  • Поправки — какво е коригирано и защо

Нека започнем с най-вълнуващото от групата!

Ново — Подобрения на езика на схемата: описания + още

Добавянето на описания към езика на схемата беше една от най-търсените функции в GraphQL.js, тъй като поддръжката за самия език на схемата беше добавена в 0.5.0 и най-накрая излезе!

С 0.7 можете да добавяте описания директно като коментари в езика на схемата GraphQL. Всеки блок за коментар, който идва преди поле, тип или дефиниция на директива, ще се използва като описание. Ето един пример:

# A small domesticated carnivorous mammal with soft fur
# See [Wikipedia entry for cat](https://en.wikipedia.org/wiki/Cat)
type Cat extends Mammal {
  name: String
  meows: Boolean
  purrs: Boolean
  scratches: Boolean
}

Синтаксисът на Markdown в описанията се поддържа изрично в спецификацията на GraphQL, така че инструменти като GraphiQL са създадени да работят с него!

Въпреки че самият език на схемата на GraphQL все още не е част от „официалната спецификация“, той се оказва толкова полезен, че планът е скоро да бъде включен там. Вече има много библиотеки, като graphql-tools, които го използват за неща като подигравка и генериране на схеми.

Версия 0.7 добави други функции, за да направи използването на езика на схемата още по-удобно:

  • Схемите, върнати от buildASTSchemaвече са изпълними. (Предупреждение: обединенията и интерфейсите не се поддържат веднага, нито анализирането и сериализирането на скаларни типове, но GraphQL.js предоставя полезно съобщение за грешка в тези случаи.)
  • Новата помощна функция buildSchema прави създаването на изпълним обект на схема от езика на схемата малко по-удобно.

Взети заедно, всички тези промени правят доста убедителен аргумент за използването на езика на схемата GraphQL.

Ново — Конвенция за именуване на коренни типове

До 0.7 нямаше официална препоръка за това какво да наименувате вашите основни типове, така че хората избираха различни алтернативи: Query, RootQuery, QueryRootType и т.н. GraphQL.js 0.7 е по-убедителен тук; предпочита: Заявка, Мутация и Абонамент. Това не е критична промяна, така че все пак можете да продължите да наименувате коренните си типове по различен начин, но ако използвате Заявка, Мутация и Абонамент, вече няма да е необходимо да указвате имената на коренните типове, когато създавате съкратена схема:

type Query {
  aString: String
}
# The following is now unnecessary if your root type is called Query
schema {
  query: Query
}

Въпреки че не е задължително, силно препоръчвам от сега нататък да използвате стандартните имена за основни типове Query, Mutation и Subscription.

Прекъсване — Резолверите по подразбиране вече получават аргументи и контекст

До 0.7.0 функцията за разрешаване по подразбиране в GraphQL не предаваше аргументи и контекст, което означаваше, че за всички, освен за най-тривиалните случаи на употреба, трябваше да дефинирате функция за разрешаване.

С 0.7 вече можете да дефинирате по-сложно поведение директно върху вашите JavaScript обекти и да изпълнявате GraphQL заявки директно върху схема, без да се налага да дефинирате резолвери. Например можете да направите това:

const query = `query {
  addOrSubtractTwo(num: 10)
}`;
const schema = buildSchema(`
  type Query {
    addOrSubtractTwo: Int
  }
`);
const rootObject = {
  addOrSubtractTwo({ num }, context){
    return num + 2 * context.polarity;
  }
};
const result = graphql(
  schema,
  query,
  rootObject,
  { polarity: -1 },
);
// result is now { data: { addOrSubtractTwo: 8 } }

Това е критична промяна, защото досега функцията за разрешаване по подразбиране не преминаваше през аргументи и контекст. Въпреки това, освен ако специално не сте програмирали функцията си да се държи по различен начин, когато получава аргументи спрямо когато не получава аргументи, трябва да сте добре.

СчупванеПо-добри грешки на GraphQLE

В 0.7 има подобрения на GraphQLError, които премахват неочакваното поведение, възникващо поради специалното третиране на грешката на много платформи. Това е, строго погледнато, подобрение. Разрушаващата промяна няма да ви засегне, освен ако не сте извикали конструктора GraphQLError изрично във вашия код, в който случай трябва да проверите diff и да коригирате реда на аргументите, за да сте сигурни, че вашият код все още работи. Може също да се наложи да актуализирате част от тестовия си код, ако сте разчитали на e.stack, тъй като GraphQLError вече предоставя трасирания на стека в някои случаи, когато не го е правил преди, и вече не записва съобщението в свойството на стека, когато стекът липсва .

Промяна, която вече беше направена в 0.6, но за която досега не се забелязваше сравнително малко, е, че GraphQLError вече включва свойство path, което ви позволява да свържете всяка грешка със съответното поле в отговора. Това е особено полезно, ако искате вашият клиент да предоставя полезни съобщения за грешка на потребителя или да коригира поведението си при кеширане въз основа на това дали полето е с грешка или не. Функцията formatError по подразбиране обаче все още я филтрира, така че ако искате да използвате path на клиента, трябва да замените функцията по подразбиране, като подадете правилния formatErrorопция за express-graphql или apollo-server:

formatError: e => ({ 
  message: e.message,
  locations: e.locations,
  path: e.path
}),

Поправки — Директиви в extendSchema и error.message

Версия 0.7 също има корекция за проблем с грешки и добавя функционалност, която липсваше в extendSchema:

  • GraphQLError вече не пише съобщения в свойството на стека на грешката, което запазва оригиналния стек и подобрява съвместимостта с инструменти, които очакват стекът да има специфичен формат.
  • Функцията extendSchema вече поддържа разширяване на схема с нови директиви.

Нова помощна програма — отделни операции

Не на последно място, новата помощна функция separateOperations ни дава още един поглед върху това как изглежда вътрешната настройка на GraphQL на Facebook.

separateOperations приема документ на GraphQL с (потенциално) много дефиниции на операции и фрагменти и връща масив от документи, всеки от които съдържа една дефиниция на операция и всички фрагменти, използвани в тази операция. Операциите са неща като заявки, мутации и абонаменти.

Как и защо Facebook използва separateOperations? По техните собствени „думи“:

Типична задача, използваща GraphQL във Facebook, изглежда така:

1. Заредете и анализирайте всички .graphql файлове, които може да съдържат операции или фрагменти.

2. Използвайте concatAST, за да създадете един AST, който съдържа всички операции и фрагменти.

3. Разделете този всеобхватен AST на отделни AST, които представляват всяка операция, която може да бъде изпратена до сървъра отделно.

separateOperationsе за третата стъпка и позволява на Facebook да кешира многото операции отделно, вместо просто да кешира един огромен документ, който съдържа всички тях.

Заключение

Това завършва нашата не толкова малка обиколка на това, което е променено в GraphQL.js 0.7. Ако искате да знаете подробности, винаги можете да проверите отличните бележки по изданието. Огромни благодарности на Lee Byron, Kevin Lacker, Robert Zhu и Rylan Hawkins, които всички работиха по това страхотно издание !

Лично аз съм много развълнуван от всички тези промени и нови функции. Темпото на развитие в екосистемата GraphQL се ускорява наистина значително. За проект с отворен код, който е едва на една година, GraphQL вече има невероятно количество сцепление и забележително жизнена общност и става все по-добър!