GraphQL API nasıl oluşturulur?

GraphQL Kapağı Nedir

Son yıllarda GraphQL, karmaşık API’ler oluşturmak için popüler bir seçim haline gelmiştir. Bunun nedeni, geleneksel REST API’lerinin bazı sınırlamalarını ortadan kaldırması ve API’nizi daha esnek ve verimli hale getirmesidir.

Bu makalede GraphQL‘i, avantajlarını ve dezavantajlarını, temel GraphQL terminolojisini tartışacağız ve GraphQL API’lerini REST API’leriyle karşılaştıracağız. Bunun da ötesinde, Back4app üzerinde kendi GraphQL API’nizi nasıl oluşturacağınızı ve bir Next.js ön ucundan ona nasıl bağlanacağınızı öğreteceğiz.

GraphQL Giriş

GraphQL, uygulama programlama arayüzleri (API’ler) geliştirmek için kullanılan bir sorgu dili ve sunucu tarafı çalışma zamanıdır. GraphQL ile istemciler, sabit bir veri kümesi sağlamak için arka uca güvenmek yerine API’den tam olarak hangi verilere ihtiyaç duyduklarını belirtebilirler.

GraphQL, hızlı ve esnek API’ler oluşturmak için modern ve verimli bir yaklaşımdır. Yerleşik bir tip sistemine sahiptir ve API aracılığıyla kullanılabilen verileri tanımlayan güçlü tipli bir şemaya dayanır. Gerçek zamanlı güncellemeleri ve abonelikleri destekler ve geliştiricilerin birden fazla veri kaynağından veri almasına olanak tanır. Bunun yanı sıra, geliştiricilere mevcut sorguları veya mutasyonları etkilemeden alanları kullanımdan kaldırma olanağı vererek API’leri geliştirmeyi kolaylaştırır.

GraphQL bir projenin başlangıcından itibaren kullanılabilir veya mevcut bir API’ye entegre edilebilir. Bazı şirketler de bunu REST ile birleştirir ve ardından adım adım geçiş yapar.

Facebook tarafından 2012 yılında dahili olarak geliştirilmiş ve daha sonra 2015 yılında açık kaynaklı hale getirilmiştir. GraphQL, tek sayfalı uygulamaların (SPA’lar) ve mobil uygulamaların yükselişiyle birlikte popülerlik kazanmıştır. Piyasaya sürülmesinden bu yana GitHub, Airbnb, Pinterest ve Shopify gibi birçok teknoloji devi tarafından benimsenmiştir.

GraphQL vs REST

GraphQL ve REST, web API’leri oluşturmak için kullanılan iki popüler yaklaşımdır.

REST (Temsili Durum Transferi), web’in yapısını tanımlayan bir yazılım mimari stilidir. 2000 yılında tanıtılmıştır ve on yılı aşkın bir süredir web API’leri oluşturmak için fiili standart olmuştur. Kaynakları manipüle etmek için GET, POST, PUT, PATCH ve DELETE gibi HTTP yöntemlerini kullanır. Her kaynak kendi uç noktasında barındırılır (aşağıdaki resme göz atın) ve bir kaynağı her talep ettiğimizde tüm “veri kümesi” döndürülür.

Bu mimari iki sorun ortaya çıkarmıştır. Bunlardan ilki yetersiz veri alma (çok az veri alma) ve aşırı veri almadır (çok fazla veri alma). Dahası, REST API’leri veri değişikliklerine abone olmamıza izin vermez.

GraphQL burada devreye giriyor. GraphQL tek bir uç noktaya sahiptir ve tek bir istekte birden fazla veri kaynağından veri sorgulamamıza olanak tanır. Tam olarak hangi veriye ihtiyacımız olduğunu tanımlamamızı sağlar. Ayrıca GraphQL, sunucuyu yoklamadan veri değişikliklerine abone olmamızı sağlar. API’mizi daha öngörülebilir ve kendi kendine belgelenebilir hale getirir.

Sonunda, GraphQL ve REST arasındaki seçim projenizin özel gereksinimlerine bağlı olacaktır. GraphQL harika olsa da basit projeler için çok fazla karmaşıklık getirebilir.

REST API vs GraphQL API

Yaygın GraphQL Terimleri

GraphQL ile çalışırken karşılaşabileceğiniz bazı yaygın terimlere göz atalım.

Tip

GraphQL bir tip sistemine sahiptir ve güçlü bir şekilde tiplendirilmiştir. Int, Float, String ve Boolean gibi bazı yerleşik skaler türlerle birlikte gelir, ancak özel türler tanımlamanıza da izin verir.

Özel bir tür şu şekilde tanımlanabilir:

type User {
    username: String!
    password: String!
    friends: [User!]
}

Şema

Şema, GraphQL API aracılığıyla kullanılabilen verilerin bir açıklamasıdır. Nesne türlerini, alanlarını ve ilişkili veri türlerini, ilişkileri, sorguları, mutasyonları ve daha fazlasını içerir. Bir şema genellikle Şema Tanımlama Dili (SDL) kullanılarak tanımlanır.

Bir şema örneği

Çözümleyici

Çözümleyici, GraphQL sorgusunda belirli bir alan için verileri alan bir işlevdir. Çözümleyici işlevleri, verileri bir veri kaynağından almaktan ve beklenen biçimde döndürmekten sorumludur.

Sorgu

Sorgu, GraphQL API’den veri için salt okunur bir istektir. Sorguları REST API’deki GET istekleri gibi düşünebilirsiniz.

Örnek:

query GetUser {
    user(id: "Wfx8o2AZrE") {
        id
        username
        fullName
    }
}

Bu sorgu tüm kullanıcıların listesini döndürür.

Mutasyon

Mutasyon, GraphQL API’deki verileri manipüle etmek için yapılan bir istektir. Mutasyonları REST API’deki POST/PUT/PATCH/DELETE istekleri gibi düşünebilirsiniz. Mutasyonlar hangi verilerin döndürüleceğini de tanımlayabilir.

Örnek:

mutation CreateAuthor {
  createAuthor(input: {fields: {firstName: "William", lastName: "Shakespeare"}}) {
    author {
      id
      createdAt
    }
  }
}

Bu mutasyon yeni bir yazar oluşturur ve yazarın id ‘sini ve createdAt değerini döndürür.

Abonelik

Abonelik, GraphQL API’den gerçek zamanlı güncellemeler için yapılan bir istektir. Abonelikler, istemcilerin sunucuyu sorgulamadan güncellemeleri mevcut oldukları anda almalarını sağlar.

Örnek:

subscription OnPostCreate($postID: ID!) {
  userAdded(postID: $postID) {
    id
    user
    content
  }
}

Bu abonelik, yeni bir gönderi oluşturulduğunda çağrılır.

GraphQL nasıl çalışır?

Bir GraphQL API uygulamak için aşağıdaki adımları gerçekleştirmeniz gerekir:

  1. Verilerinizi bir şema kullanarak tanımlama
  2. Çözümleyicileri veri kaynaklarına bağlama
  3. Sorgular ve mutasyonlar yazın
  4. Öngörülebilir sonuçlar elde edin

Back4app veya benzer bir hizmet kullanıldığında bu işin büyük bir kısmı soyutlanacaktır. Siz veritabanı modellerini oluştururken Back4app otomatik olarak GraphQL şemasını ve dokümantasyonunu oluşturacaktır. Bu konuda daha fazla bilgiyi eğitimin pratik bölümünde bulabilirsiniz.

GraphQL’in avantajları nelerdir?

GraphQL’in öğrenilmesi kolaydır, kullanıcılar birden fazla kaynaktan veri toplayabilir ve API’niz için modern bir dildir.

Şema

GraphQL API, güçlü tiplendirilmiş bir şemaya dayanmaktadır. Bu, tip hatalarını ve hataları çalışma zamanı yerine derleme zamanında tespit etmenizi sağlar. Dahası, GraphQL API’leri içe dönüktür, yani herhangi bir harici belgeye dayanmadan kendileri hakkında bilgi sağlayabilirler.

Esnek ve Verimli Veri Getirme

GraphQL API’leri, istemcilerin tam olarak neye ihtiyaç duyduklarını belirtmelerine izin verdiği için son derece esnektir. Bu, yetersiz ve aşırı erişim sorununu çözer ve API isteklerinin sayısını azaltır. Daha az API isteği daha iyi performansla sonuçlanır.

API Güncellemeleri

GraphQL ile, mevcut sorguları etkilemeden yeni alanları ve türleri sorunsuz bir şekilde entegre edebilirsiniz. Kullanımdan kaldırılmış ve güncelliğini yitirmiş alanlar da araçlardan gizlenebilir. GraphQL API’leri uygulamalara yeni özelliklere sürekli erişim sağlar ve daha temiz, daha sürdürülebilir sunucu kodunun geliştirilmesini teşvik eder.

Gerçeğin Tek Kaynağı

Bir GraphQL şeması, bir GraphQL uygulamasında tek bir doğruluk kaynağı belirler. Bir kuruluşa tüm API’sini yönetmek için kolay bir yol sunar.

GraphQL Uzantıları

GraphQL, GraphQL geliştiricilerinden oluşan büyük bir topluluk tarafından desteklenir ve birçok açık kaynak uzantısıyla birlikte gelir. Bu uzantılar sayfalama, önbelleğe alma, performans izleme gibi yaygın API görevlerinden bazılarını basitleştirir.

GraphQL’in dezavantajları nelerdir?

Karmaşıklık

GraphQL, bir veri sorgusundaki işlerin çoğunu sunucu tarafına kaydırarak arka uçları daha karmaşık hale getirir. Bunun da ötesinde, sorgu dili ve şema tanımları daha fazla ön planlama ve bakım gerektirebilir.

Öğrenme eğrisi

GraphQL, REST’e göre daha dik bir öğrenme eğrisine sahiptir. Ayrıca, GraphQL geliştiricileri genellikle REST geliştiricilerinden daha pahalıdır ve bulunması daha zordur.

Standardizasyon Eksikliği

GraphQL’e yönelik temel eleştirilerden biri, uygulamasında standardizasyon eksikliğidir. REST API’leri iyi oluşturulmuş bir dizi ilke ve en iyi uygulamaya sahipken GraphQL dokümantasyonu yalnızca bir şeylerin nasıl uygulanacağına dair bazı genel ipuçları sağlar. Bu durum GraphQL API’lerinin nasıl tasarlandığı ve kullanıldığı konusunda tutarsızlıklara ve kafa karışıklığına yol açabilir.

Güvenlik

GraphQL ile ilgili harika olan şey, istemcilerin tam olarak ihtiyaç duydukları şeyi talep edebilmeleridir, ancak diğer yandan bu potansiyel bir güvenlik riski olabilir. Kötü niyetli sorguların yürütülmesini önlemek için kullanıcı girdisini düzgün bir şekilde doğrulamak ve sterilize etmek önemlidir.

GraphQL API nasıl oluşturulur?

Makalenin bu bölümünde Back4app ile bir GraphQL API ‘nin nasıl oluşturulacağı ve Next.js ön ucundan bu API ‘ye nasıl bağlanılacağı anlatılmaktadır.

Ön Koşullar

  • JavaScript ES6 ile deneyim
  • React ve Next.js ile deneyim
  • GraphQL hakkında temel anlayış

Back4app nedir?

Back4app, açık kaynaklı yazılımlar üzerinde çalışan istisnai bir Hizmet Olarak Arka Uç (BaaS) çözümüdür. Platform, kullanıcıların web ve mobil uygulamaları daha kolay ve daha hızlı geliştirmelerine olanak tanıyan çok çeşitli özellikler sunar. İşletmelerin arka uç veya altta yatan altyapı hakkında endişelenmelerine gerek kalmadan iş mantığına odaklanmalarını sağlar.

Back4app, özelliklerle dolu kullanımı kolay bir gösterge tablosu ve bir komut satırı arayüzü (CLI) ile birlikte gelir. Ayrıca Node.js, Flutter, React Native, Android, Angular, iOS ve daha fazlası gibi çeşitli popüler araçlar için Yazılım Geliştirme Kitleri (SDK’lar) sağlar.

Back4app, her uygulamanın ihtiyaçlarını karşılayabilecek basit bir fiyatlandırma modeli izliyor. Ayrıca test ve prototipleme için harika olan ücretsiz bir plan (kredi kartı gerekmiyor) sunuyorlar.

Back4app hakkında daha fazla bilgi edinmek ister misiniz? Göz atın Neden Back4app kullanmalı?

Proje Tanıtımı

Basit bir web TODO uygulaması oluşturacağız. Uygulama iki bölümden oluşacak: arka uç ve ön uç. Arka uç bir GraphQL API tarafından desteklenecek ve Back4app üzerinde konuşlandırılacaktır. Öte yandan ön uç, Next.js çerçevesi kullanılarak TypeScript ile yazılacak. Ön ucu arka uca bağlamak için Apollo İstemcisini kullanacağız.

Nihai uygulama şu şekilde görünecektir:

back4app-graphql Proje Önizlemesi

Arka uç

Back4app Uygulaması Oluşturun

Aşağıdaki adımlara devam etmek için bir Back4app hesabınızın olması gerekir. Zaten bir hesabınız varsa, lütfen giriş yapın. Aksi takdirde, ücretsiz bir hesap için kaydolmaktan çekinmeyin.

Back4app’i kullanmak için ilk adım bir uygulama oluşturmaktır. Kontrol panelinize giriş yaptıktan sonra, mevcut uygulamalarınızın bir listesini görüntüleyebileceksiniz. Yeni bir uygulama oluşturmak için “Yeni bir uygulama oluştur” seçeneğine tıklayın.

Back4app Uygulama Oluşturma

Bir GraphQL API oluşturduğumuz için, “Backend as a Service” seçeneğini seçin ve uygulamanız için benzersiz bir ad belirleyin. Ek olarak, veritabanı türü olarak “NoSQL” seçin.

Back4app’in veritabanı, uygulama katmanı, ölçeklendirme, yedeklemeler ve güvenlik dahil olmak üzere uygulamanız için gereken her şeyi yapılandırmasını sabırla bekleyin.

Kurulum tamamlandıktan sonra, uygulamanızın kontrol paneline yönlendirileceksiniz.

Back4app Uygulaması Oluşturuldu

Veritabanı Modellerini Tanımlama

Basit bir TODO uygulaması oluşturduğumuz için yalnızca bir veritabanı modeline ihtiyacımız olacak.

Başlamak için Back4app kontrol panelinize gidin ve kenar çubuğunda “Veritabanı” seçeneğini bulun. Buradan “Bir sınıf oluştur “u seçin ve ona “Görev” adını verin. “Genel Okuma ve Yazma Etkin” seçeneğini seçtiğinizden emin olun ve ardından “Sınıf oluştur ve sütun ekle” seçeneğine tıklayın.

Back4app Tanımlama Modeli

Sonraki sütunları ekleyin:

+-----------+------------------+---------------+----------+
| Data type | Name             | Default value | Required |
+-----------+------------------+---------------+----------+
| String    | name             | <leave blank> | yes      |
+-----------+------------------+---------------+----------+
| String    | description      | <leave blank> | no       |
+-----------+------------------+---------------+----------+
| Boolean   | isDone           | false         | no       |
+-----------+------------------+---------------+----------+

Veritabanı modelinizi oluşturduktan sonra dört veritabanı sütununun otomatik olarak eklendiğini göreceksiniz:

  1. objectId nesnenizin birincil anahtarıdır
  2. updatedAt son güncellemenin zaman damgasıdır
  3. createdAt, oluşturma zaman damgasıdır
  4. ACL “Erişim Kontrol Listesi “ni tanımlar

Bunları aklınızda tutun çünkü eğitimin ilerleyen bölümlerinde GraphQL sorguları ve mutasyonları üzerinde çalışırken bunlara ihtiyaç duyacağız.

Back4app kontrol paneline aşina olmak için iki örnek görev eklemeyi deneyin, örn:

+-----------------+----------------------------------------+--------+
| name            | description                            | isDone |
+-----------------+----------------------------------------+--------+
| GraphQL backend | Create a GraphQL backend via Back4app. | false  |
+-----------------+----------------------------------------+--------+
| Learn GraphQL   | Learn the basics of GraphQL.           | true   |
+-----------------+----------------------------------------+--------+

GraphQL API Konsolu

GraphQL API Konsolu, GraphQL sorgularını ve mutasyonlarını kodda uygulamadan önce test etmemizi sağlar. Konsola erişmek için kenar çubuğunda “API” ve ardından “Konsol > GraphQL” öğesini seçin.

Back4app GraphQL Konsolu

Konsolun kullanımı son derece kolaydır. Sol tarafta özel sorgularımızı ve mutasyonlarımızı girebiliyoruz ve ardından sonuçlar sağ tarafta görüntüleniyor.

Her şeyin çalışıp çalışmadığını kontrol etmek için aşağıdaki sorguyu çalıştırın:

query CheckHealth {
    health
}

Aşağıdaki JSON yanıtını almalısınız:

{
  "data": {
    "health": true
  }
}

Back4app ile ilgili en güzel şeylerden biri Parse tabanlı olmasıdır. Veritabanı modelimizi oluştururken Parse bizim için GraphQL’i otomatik olarak yapılandırdı. Bu, bir GraphQL şeması, dokümanlar vb. oluşturmayı içerir.

Veritabanındaki görevleri ve ayrıntılarını listelemeyi deneyelim:

query GetTasks {
  tasks {
    count
    edges {
      node {
        id
        name
        description
        isDone
      }
    }
  }
}

Benzer bir yanıt almalısınız:

{
  "data": {
    "tasks": {
      "count": 2,
      "edges": [
        {
          "node": {
            "id": "VGFzazpXQkJzSkRtV2xU",
            "name": "GraphQL backend",
            "description": "Create a GraphQL backend via Back4app.",
            "isDone": false
          }
        },
        {
          "node": {
            "id": "VGFzazpnM2lhNzdwUXBp",
            "name": "Learn GraphQL",
            "description": "Learn the basics of GraphQL.",
            "isDone": true
          }
        }
      ]
    }
  }
}

Belirli bir nesneyi almak, nesneleri oluşturmak, güncellemek vb. benzer şekilde yapılır. Bu sorguları ve mutasyonları eğitimin ilerleyen bölümlerinde açıklayacağım için şimdi çok fazla ayrıntıya girmeyeceğim. Ayrıca, Back4app dokümanları bu konuları iyi bir şekilde ele almaktadır:

  1. Nesne oluşturma
  2. Nesne alma
  3. Nesneleri bulma
  4. Bir nesneyi güncelleme
  5. Nesne silme
  6. Kimlik Doğrulama

Arka uç kısmı için bu kadar. Bir sonraki bölümde, ön uç üzerinde çalışmaya başlayacağız.

Ön Uç

Sonraki Uygulamayı Oluştur

Bir Next.js projesini önyüklemenin en kolay yolu create-next-app yardımcı programını kullanmaktır. Terminalinizi açın ve aşağıdaki komutu çalıştırın:

$ yarn create next-app

√ What is your project named? ... back4app-graphql
√ Would you like to use TypeScript with this project? ... No
√ Would you like to use ESLint with this project? ... Yes
√ Would you like to use the `src/` directory with this project? ... No
√ Would you like to use the experimental `app/` directory with this project? ... No
√ What import alias would you like configured? ... @/*

Successfully created a Next.js app.

Ardından, geliştirme sunucusunu çalıştırın:

$ yarn dev

http://localhost:3000 adresine gidin ve varsayılan Next.js açılış sayfasını görmelisiniz.

SonrakiJS Varsayılan Açılış Sayfası

ChakraUI

UI/UX oluşturma sürecini hızlandırmak ve basitleştirmek için ChakraUI kullanacağız. Chakra UI, React uygulamalarınızı oluşturmak için ihtiyacınız olan her şeyi size sunan basit, modüler ve erişilebilir bir bileşen kütüphanesidir.

Herhangi bir sorunla karşılaşmanız durumunda ChakraUI: Next.js ile çalışmaya başlama.

Yüklemek için çalıştırın:

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion

Ardından, _pages/app.tsx dosyanıza gidin ve uygulamanızı ChakraProvider ile şu şekilde sarın:

// pages/_app.tsx

import "../styles/globals.css";
import type {AppProps} from "next/app";
import {ChakraProvider} from "@chakra-ui/react";

export const theme = extendTheme({});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}

export default MyApp;

ChakraProvider‘ı içe aktarmayı unutmayın:

import {ChakraProvider} from "@chakra-ui/provider";

Rastgele renk yanıp sönmelerini önlemek için renk modu komut dosyasını içerikten önce yüklediğinizden emin olun. Bunu yapmak için _document.js dosyasını şu şekilde kullanabilirsiniz:

// pages/_document.tsx

import {ColorModeScript} from "@chakra-ui/react";
import { Html, Head, Main, NextScript } from "next/document";
import {theme} from "@/pages/_app";

export default function Document() {
  return (
    <Html lang='en'>
      <Head />
      <body>
        <ColorModeScript initialColorMode={theme.config.initialColorMode} />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Harika, ChakraUI’yi başarıyla yüklediniz.

Kullanıcı Arayüzü

Devam edelim, kullanıcı arayüzünü oluşturalım. Web uygulamamız aşağıdaki iki sayfaya sahip olacak:

  1. / görevlerin listesini görüntüler
  2. create/ görev oluşturmak için formu görüntüler

pages/index.tsx dosyasını aşağıdaki içerikle değiştirerek başlayın:

// pages/index.tsx

import type {NextPage} from "next";
import {
    Button, Card, CardBody, Container,
    Heading, HStack, Stack, Text, VStack
} from "@chakra-ui/react";
import Link from "next/link";

let data = {
  "tasks": {
    "count": 2,
    "edges": [
      {
        "node": {
          "id": "VGFzazpXQkJzSkRtV2xU",
          "name": "GraphQL backend",
          "description": "Create a GraphQL backend via Back4app.",
          "isDone": false
        }
      },
      {
        "node": {
          "id": "VGFzazpnM2lhNzdwUXBp",
          "name": "Learn GraphQL",
          "description": "Learn the basics of GraphQL.",
          "isDone": true
        }
      }
    ]
  }
};

const ListPage: NextPage = () => {

  const handleMarkAsDone = async (id: string, isDone: boolean) => {
    console.log("TODO: mark task as done and refetch");
  };

  const handleDelete = async (id: string) => {
    console.log("TODO: delete task and refetch");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/create">
            <Button size="sm" colorScheme="blue">
              Create task
            </Button>
          </Link>
        </HStack>
        <VStack spacing={4}>
          {data.tasks.edges.map((edge) => {
            let task = edge.node;
            return (
              <Card key={task.id} w="100%">
                <CardBody>
                  <Stack direction="column">
                    <Heading as="h2" size="md">
                      {task.isDone ? "✔️" : "❌"}{" "}
                      {task.name}
                    </Heading>
                    <Text>
                      {task.description}
                    </Text>
                    <Stack direction="row" pt={2}>
                      <Button size="sm" colorScheme="blue" onClick={() => handleMarkAsDone(task.id, task.isDone)}>
                        Toggle done
                      </Button>
                      <Button size="sm" colorScheme="red" onClick={() => handleDelete(task.id)}>
                        Delete
                      </Button>
                    </Stack>
                  </Stack>
                </CardBody>
              </Card>
            );
          })}
        </VStack>
      </Container>
    </>
  );
};

export default ListPage;
  1. Kullanıcı arayüzünü tasarlamak için ChakraUI kullandık.
  2. Görevler şu anda data adlı statik diziden yüklenmektedir.
  3. Daha sonra GraphQL API istekleri göndermek için handleMarkAsDone() ve handleDelete() işlevlerini kullanacağız.

Ardından, pages klasörü içinde aşağıdaki içeriğe sahip bir create.tsx dosyası oluşturun:

// pages/create.tsx

import type {NextPage} from "next";
import {
  Button, Card, CardBody, CardHeader, Container, FormControl,
  FormLabel, Heading, HStack, Input, Stack, Switch, Text
} from "@chakra-ui/react";
import Link from "next/link";
import {useState} from "react";
import {useRouter} from "next/router";

const CreatePage: NextPage = () => {
  const router = useRouter();

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [isDone, setIsDone] = useState(false);

  const [formError, setFormError] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    console.log("TODO: call the GraphQL API and redirect");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/">
            <Button size="sm" colorScheme="blue">
              View list
            </Button>
          </Link>
        </HStack>
        <Card>
          <CardHeader>
            <Stack direction="column">
              <Heading as="h2" size="md">Create task</Heading>
              <Text>
                Fill out the form and press &quot;Create&quot; to create a new task.
              </Text>
            </Stack>
          </CardHeader>
          <CardBody>
            <form onSubmit={handleSubmit}>
              <Stack direction="column">
                {formError && <Text color="red.500" fontWeight="bold">{formError}</Text>}
                <FormControl>
                  <FormLabel>Name</FormLabel>
                  <Input type="text" value={name} onChange={(event) => setName(event.target.value)}/>
                </FormControl>
                <FormControl>
                  <FormLabel>Description</FormLabel>
                  <Input type="text" value={description} onChange={(event) => setDescription(event.target.value)}/>
                </FormControl>
                <FormControl display="flex" alignItems="center">
                  <FormLabel mb="0">
                    Is done?
                  </FormLabel>
                  <Switch isChecked={isDone} onChange={() => setIsDone(!isDone)}/>
                </FormControl>
                <Button size="sm" colorScheme="blue" type="submit">Create task</Button>
              </Stack>
            </form>
          </CardBody>
        </Card>
      </Container>
    </>
  );
};

export default CreatePage;
  1. Kullanıcı arayüzünü oluşturmak için yine ChakraUI bileşenlerini kullandık.
  2. Görevleri oluşturmak için React kontrollü bir form oluşturduk.
  3. handleSubmit() işlevi daha sonra bir API isteği göndermek için kullanılacaktır.

Web sunucunuzu yeniden başlatın ve http://localhost:3000 adresinden web uygulamanızı ziyaret edin. Sabit kodlanmış iki görevi görmelisiniz. Ardından, görev oluşturma formunu görmek için “Görev oluştur” seçeneğine tıklayın.

Back4app GraphQL Görev Oluşturma

GraphQL İstemcisi

Ön uçtan bir GraphQL API’ye bağlanmak için öncelikle bir GraphQL İstemcisi yüklemeniz gerekir. Apollo İstemcisini kullanmanızı öneririm, çünkü kurulumu kolaydır, görüş bildirmez ve çok fazla boilerplate gerektirmez.

apollo/client ve graphql yükleyerek başlayın:

$ yarn add @apollo/client graphql

İstemciyi başlatmak için Back4app API kimlik bilgilerinizi sağlamanız gerekir. Kimlik bilgilerinizi edinmenin en kolay yolu GraphQL Konsolunuza gitmek ve başlıklara dikkat etmektir.

Back4app GraphQL Kimlik Bilgileri

API anahtarlarınızı kaynak kodda göstermek istemediğiniz için proje kök dizininde aşağıdaki içeriğe sahip bir .env.local dosyası oluşturun:

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<YOUR_PARSE_APP_ID>
NEXT_PUBLIC_PARSE_MASTER_KEY=<YOUR_PARSE_MASTER_KEY>
NEXT_PUBLIC_PARSE_CLIENT_KEY=<YOUR_PARSE_CLIENT_KEY>

Ardından pages/_app.tsx adresine gidin ve Apollo istemcisini başlatın, ardından uygulamanızı ApolloProvider ile şu şekilde sarın:

// pages/_app.tsx

// ...
import {ApolloClient, ApolloProvider, InMemoryCache} from "@apollo/client";

const client = new ApolloClient({
  uri: "https://parseapi.back4app.com/graphql",
  headers: {
    "X-Parse-Application-Id": process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID,
    "X-Parse-Master-Key": process.env.NEXT_PUBLIC_PARSE_MASTER_KEY,
    "X-Parse-Client-Key": process.env.NEXT_PUBLIC_PARSE_CLIENT_KEY,
  },
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <ApolloProvider client={client}>
        <Component {...pageProps} />
      </ApolloProvider>
    </ChakraProvider>
  );
}

Ön ucunuzun yeniden derlenmesini bekleyin, ardından web uygulamanızı ziyaret edin ve konsolda herhangi bir hata olup olmadığını kontrol edin. Hata olmaması bağlantının başarılı olduğu anlamına gelir.

GraphQL Sorguları ve Mutasyonları

Yapmanız gereken son şey GraphQL sorgularınızı ve mutasyonlarınızı tanımlamak ve ardından bunları React kodunuzdan çağırmaktır.

IDE’nizde GraphQL kod yardımını etkinleştirmek için Back4app GraphQL Console’a gidin, kenar çubuğunda “Schema “yı seçin ve SDL olarak indirin. Ardından proje kök dizininde schema.graphql adında yeni bir dosya oluşturun ve SDL içeriğini yapıştırın.

İlk olarak pages/index.tsx dosyasına gidin ve içe aktarımlardan sonra aşağıdaki sorguları ekleyin:

// pages/index.tsx

const GET_TASKS = gql`
  query GetTasks {
    tasks {
      count
      edges {
        node {
          id
          name
          description
          isDone
        }
      }
    }
  }
`;

const UPDATE_TASK = gql`
  mutation UpdateTask($id: ID!, $isDone: Boolean!) {
    updateTask(input: { id: $id, fields: { isDone: $isDone } }) {
      task {
        isDone
        updatedAt
      }
    }
  }
`;

const DELETE_TASK = gql`
  mutation DeleteTask($id: ID!) {
    deleteTask(input: { id: $id }) {
      task {
        id
      }
    }
  }
`;

Bu üç sorgu oldukça açıklayıcıdır. Birincisi tüm görevlerin bir listesini döndürür, ikincisi belirli bir görevin isDone özelliğini günceller ve üçüncüsü belirli bir görevi siler.

Ardından, ListPage ‘in üst kısmını aşağıdaki gibi değiştirin:

// pages_index.tsx

// ...

const ListPage: NextPage = () => {

  const {loading, error, data, refetch} = useQuery(GET_TASKS);
  const [deleteTask] = useMutation(DELETE_TASK);
  const [updateTask] = useMutation(UPDATE_TASK);

const handleMarkAsDone = async (id: string, isDone: boolean) => {
    try {
      const updateTaskResponse = await updateTask({
        variables: {id: id, isDone: !isDone}
      });
      console.debug(updateTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      const deleteTaskResponse = await deleteTask({
        variables: {id: id},
      });
      console.debug(deleteTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  if (error) return <p>Oops, something went wrong.</p>;
  if (loading) return <Spinner/>;

  // ...
};

export default ListPage;
  1. GET_TASKS sorgusunu çalıştırmak ve sonucu saklamak için useQuery() kullandık.
  2. GraphQL mutasyonlarını tanımlamak için useMutation() fonksiyonunu kullandık.
  3. handleMarkAsDone() ve handleDelete() işlevlerini mutasyon kancalarını kullanacak şekilde güncelledik.

Devam edersek, pages/create.tsx dosyasını benzer şekilde değiştirin:

const CREATE_TASK = gql`
  mutation CreateTask($name: String!, $description: String, $isDone: Boolean!) {
    createTask(
      input: {
        fields: { name: $name, description: $description, isDone: $isDone }
      }
    ) {
      task {
        id
      }
    }
  }
`;

const CreatePage: NextPage = () => {

  // ...

  const [createTask] = useMutation(CREATE_TASK);

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    createTask({
      variables: {name: name, description: description, isDone: isDone}
    }).then(response => {
      router.push("/");
    });
  };

  // ...
};

export default CreatePage;

İthalatı unutmayın:

import {gql, useMutation, useQuery} from "@apollo/client";

Harika, işte bu!

Geliştirme sunucunuzu yeniden başlatın ve web uygulamanızı ziyaret edin. Görevlerin veritabanından yüklenip yüklenmediğini kontrol edin, yeni bir görev oluşturmayı, tamamlandı olarak işaretlemeyi ve silmeyi deneyin.

Sonuç

Sonuç olarak GraphQL, esnek sorgulama yetenekleri ve verimli veri alımı nedeniyle karmaşık API’ler oluşturmak için iyi bir seçimdir. Geleneksel REST API’ye göre birçok avantajı olsa da, bir projeye başlarken göz önünde bulundurmanız gereken bazı dezavantajları vardır.

Bu makalede GraphQL’in avantajlarını ve dezavantajlarını tartıştık, REST API’lerle karşılaştırdık ve bazı temel GraphQL terminolojisini tanıttık. Artık Back4app üzerinde kendi basit GraphQL API’nizi oluşturabilmeli ve bir JavaScript ön ucundan buna bağlanabilmelisiniz.

Son kaynak kodunu GitHub reposundan alabilirsiniz.

SSS

GraphQL nedir?

GraphQL, güçlü ve esnek API’ler geliştirmek için kullanılan bir sorgulama dili ve sunucu taraflı çalışma zamanıdır.

REST ile GraphQL arasındaki temel farklar nelerdir?

REST, web servisleri oluşturmak için standart ve basit bir yaklaşımdır; GraphQL ise daha esnek sorgulama yetenekleri sunar ve veri az veya fazla çekme sorunlarını ortadan kaldırır.

Yaygın olarak kullanılan GraphQL terimleri nelerdir?

– Şema, bir GraphQL API üzerinden erişilebilecek verilerin tanımıdır.
– Çözücü (Resolver), GraphQL sorgusundaki belirli bir alanın verisini getiren işlevdir.
– Sorgu (Query), GraphQL API’den veri almak için yapılan salt okunur bir istektir.
– Mutasyon (Mutation), GraphQL API’deki verileri değiştirmek için yapılan istektir.
– Abonelik (Subscription), GraphQL API’den gerçek zamanlı güncellemeler almak için yapılan istektir.

GraphQL API nasıl oluşturulur?

1. Back4app üzerinden ücretsiz bir hesap oluşturun.
2. Veritabanı modellerini tasarlayın.
3. Back4app GraphQL API Konsolu üzerinden sorguları ve mutasyonları yazın.
4. Ön uç projenize bir GraphQL istemcisi (örneğin Apollo veya Relay) kurun.
5. İstemciyi başlatın ve GraphQL API’ye bağlanın.


Leave a reply

Your email address will not be published.