Learning
GraphQL

Típusok és sémák részletesen

Típusok (object/scalar/enum/interface/union/input) és pagination minták GraphQL-ben.

Típusok és sémák részletesen

A GraphQL típusrendszere az egyik legnagyobb erőssége. Erősen típusos: minden adat típusa ismert fordítási időben, ami lehetővé teszi az automatikus validációt és a fejlesztői eszközök (autocomplete, hibakeresés) hatékony működését.

Object típusok

Az alaptípus: összetett adatobjektumok leírása.

type Article {
  id: ID!
  title: String!
  slug: String!
  content: String!
  excerpt: String
  coverImage: String
  publishedAt: String
  author: User!
  tags: [String!]!
  viewCount: Int!
  isPublished: Boolean!
}

Scalar típusok

Beépített primitívek mellett egyéni skalárokat is definiálhatsz:

scalar Date
scalar Email
scalar URL
scalar JSON

type Event {
  id: ID!
  name: String!
  startDate: Date!
  website: URL
  metadata: JSON
}

Az egyéni skalárokat a szerveroldalon implementálni kell (szerializáció, deszializáció, validáció).

Enum típusok

Felsorolt értékek, amelyek csak meghatározott értékeket vehetnek fel:

enum OrderStatus {
  PENDING
  PROCESSING
  SHIPPED
  DELIVERED
  CANCELLED
  REFUNDED
}

enum SortOrder {
  ASC
  DESC
}

type Order {
  id: ID!
  status: OrderStatus!
  items: [OrderItem!]!
}

Interface típusok

Közös mezőket definiálnak, amelyeket több típus is implementálhat:

interface Node {
  id: ID!
}

interface Timestamped {
  createdAt: String!
  updatedAt: String!
}

type User implements Node & Timestamped {
  id: ID!
  name: String!
  email: String!
  createdAt: String!
  updatedAt: String!
}

type Post implements Node & Timestamped {
  id: ID!
  title: String!
  content: String!
  createdAt: String!
  updatedAt: String!
}

Union típusok

Különböző típusok egyikét reprezentálják – hasznos keresési eredményeknél:

union SearchResult = User | Post | Comment | Tag

type Query {
  search(query: String!): [SearchResult!]!
}

A kliensen inline fragment-ekkel kezeljük:

query Search($term: String!) {
  search(query: $term) {
    ... on User {
      name
      email
    }
    ... on Post {
      title
      excerpt
    }
    ... on Comment {
      text
      author {
        name
      }
    }
  }
}

Input típusok

Csak mutation argumentumként használhatók:

input PaginationInput {
  page: Int = 1
  limit: Int = 20
}

input FilterInput {
  status: OrderStatus
  dateFrom: String
  dateTo: String
  search: String
}

type Query {
  orders(
    filter: FilterInput
    pagination: PaginationInput
    sort: SortOrder = DESC
  ): OrderConnection!
}

Pagination (lapozás) sémák

Kétféle elterjedt minta létezik:

Offset-alapú lapozás:

type PaginatedPosts {
  items: [Post!]!
  total: Int!
  page: Int!
  totalPages: Int!
  hasNextPage: Boolean!
}

Cursor-alapú lapozás (Relay-stílus):

type PostEdge {
  node: Post!
  cursor: String!
}

type PostConnection {
  edges: [PostEdge!]!
  pageInfo: PageInfo!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

A cursor-alapú lapozás hatékonyabb nagy adathalmazoknál, és konzisztens marad, ha közben új elemek kerülnek az adatbázisba.

Rövid összefoglaló

  • Az object típusok összetett adatobjektumokat írnak le.
  • Az enum típusok meghatározott értékkészletű mezőket definiálnak.
  • Az interface típusok közös mezőket határoznak meg több típus számára.
  • Az union típusok különböző típusok egyikét reprezentálják (pl. keresési eredmények).
  • Az input típusok kizárólag mutation argumentumként használhatók.
  • A lapozáshoz offset-alapú és cursor-alapú mintákat egyaránt alkalmaznak.

On this page