Основные принципы GraphQL в качестве руководства (часть 1)
GraphQL — это популярный язык запросов для API, разработанный Apollo, который позволяет клиентам точно указывать, какие данные им нужны, и получать в ответ только эти данные. Хотя он обеспечивает значительные преимущества по сравнению с REST, он также может создавать сложности, затрудняя поддержку надежного и согласованного API. Чтобы решить эту проблему, Apollo выпустила набор руководящих принципов под названием Принципы GraphQL, чтобы помочь разработчикам создавать поддерживаемые и масштабируемые API-интерфейсы GraphQL.
В этой статье мы будем использовать некоторые из этих принципов в качестве руководства и приведем несколько примеров их применения на практике (не обязательно настоящие принципы, но их применение).
В наших примерах мы будем использовать решение для веб-сайта электронной коммерции, который продает товары.
и) Иерархический
Первый принцип Principled GraphQL заключается в том, что API должен быть иерархическим. API должен иметь четко определенную схему, описывающую модель данных и ее отношения. Определив схему, клиенты могут перемещаться по графу данных структурированным образом, снижая риск избыточной или недостаточной выборки данных.
В нашем кодовом решении мы можем определить схему, включающую типы «Продукт» и «Пользователь», где продукт связан с создавшим его пользователем. Мы также можем определить запрос, который позволяет клиентам получать все продукты, связанные с конкретным пользователем, например:
type User { id: ID! name: String! products: [Product!]! } type Product { id: ID! name: String! description: String! price: Float! seller: User! } type Query { user(id: ID!): User }
ii) Ориентированность на продукт
Второй принцип Principled GraphQL заключается в том, что API должен быть ориентирован на продукт, а это означает, что он должен фокусироваться на потребностях продукта, а не на деталях реализации API. API должен предоставлять четкую и краткую документацию, которую легко понять разработчикам.
Итак, в этом случае мы можем определить мутацию, которая позволяет клиентам на нашем веб-сайте электронной коммерции создавать новый продукт, например:
type Mutation { createProduct(name: String!, description: String!, price: Float!): Product! }
iii) Строго типизированный
Третий принцип Principled GraphQL заключается в том, что API должен быть строго типизирован. Это означает, что API должен иметь четко определенную схему, определяющую модель данных и ее отношения. Используя строго типизированную схему, клиенты могут быть уверены, что запрашиваемые ими данные достоверны и непротиворечивы.
г) декларативный
Четвертый принцип Principled GraphQL заключается в том, что API должен быть декларативным. Это означает, что клиенты должны иметь возможность точно указывать, какие данные им нужны, и получать в ответ только эти данные. Делая API декларативным, клиенты могут снизить риск избыточной или недостаточной выборки данных.
Ниже мы можем определить запрос, который позволяет клиентам получать все продукты, связанные с конкретным пользователем, например:
query GetUserProducts($userId: ID!) { user(id: $userId) { products { id name price } } }
в) Безопасный
Пятый принцип Principled GraphQL заключается в том, что API должен быть безопасным. Это означает, что API должен предоставлять надежные и детализированные механизмы аутентификации и авторизации, чтобы гарантировать, что только авторизованные клиенты могут получить доступ к данным. API также должен быть разработан с учетом требований безопасности, чтобы предотвратить такие атаки, как внедрение SQL и межсайтовые сценарии.
Таким образом, в этом случае мы можем определить механизм аутентификации, который требует от клиентов предоставления действительного токена доступа для доступа к API, например:
type Query { me: User! } type Mutation { createProduct(name: String!, description: String!, price: Float!): Product! } type User { id: ID! name: String! email: String! } type Product { id: ID! name: String! description: String! price: Float! seller: User! } input CreateProductInput { name: String! description: String! price: Float! } type AuthPayload { token: String! user: User! } type Mutation { login(email: String!, password: String!): AuthPayload! signup(name: String!, email: String!, password: String!): AuthPayload! }
Конец части 1 😃
Мы охватили довольно много земли. На этом мы остановимся и продолжим это в новой части двух серий этого поста! Обязательно последуют дополнительные заметки, когда мы рассмотрим последнюю и последнюю часть серии.
Следите за обновлениями!