Nedir Bu GraphQL?

Akın Çam
emlakjet
Published in
5 min readOct 10, 2022

2007 yılında IOS ve Android cihazların çıkışıyla birlikte Facebook, mobil uygulama tarafında eşsiz bir kullanıcı deneyimi sunmak için çalışmalara başladı ve iki platform içinde yeni uygulamalarını yayına aldı. 2012 yılında çalışmalarını ilerleterek ‘Learn once, write anywhere’ mottosu ile cross platform bir uygulama geliştirmeye başladıkları yolda birçok sorun ile karşılaştılar. Bu sorunlara çözüm olarak GraphQL’i geliştirdiler. Peki nedir bu GraphQL?

GraphQL API’ler için bir sorgulama dilidir/syntaxtır. Belirli bir veritabanına ya da depolama yapısına bağlı değildir. Bunun yerine mevcut geliştirmeleriniz ve verileriniz tarafından desteklenerek veri sorgulamak ya da veriler üzerinde işlem yapmak için kullanılan açık kaynaklı rest tabanlı bir web servis sorgulama dilidir. Facebook tarafından 2012 yılında geliştirilmiş, 2015 yılında açık kaynaklı olarak duyurulmuştur.

Nasıl Ortaya Çıktı?

Facebook 2004 yılında kurulduğu dönemde masaüstü uygulamaları aktif olarak kullanılıyordu. 2007 yılında IOS ve Android cihazların ortaya çıkışı ile birlikte Facebook kullanıcılarına en iyi web mobil deneyimini sunmak için çalışmalara başladı. Bu çalışmaların aksine işletim sistemleri ilk aşamada o alana hiç önem vermediler. Bunun üzerine Facebook mobil uygulama geliştirme çalışmalarına başladı. Yıl 2012 ye geldiğinde Facebook her iki platformda da çalışabilecek tek bir uygulama geliştirme kararı aldı ve ‘Learn once, write anywhere’ mottosu ile yeni Facebook mobil uygulamayı geliştirmeye başladı ve bazı sorunlarla karşılaştı:

Slow on network: Bir özellik için gerekli olan verileri tek bir api sağlamıyordu. Bunun için birden çok api’ye istek atmak gerekiyordu.

Client/Server relationship: Backend kodunda yapılan herhangi bir değişiklik direkt uygulamayı etkileyebiliyordu. Bu da uygulamanın birçok hata almasına hatta çökmesine sebep oluyordu.

Maintenance-Documentation: Hızlı dönüşüm süreci ile birlikte uygulama bakım ve dokümantasyon tarafından eksikler meydana gelmeye başlamıştı

Bu sorunların üstesinden gelmek için yeni bir api yaklaşımına gitti ve GraphQL teknolojisini geliştirdi.

Avantajları & Dezavantajları

Avantajları:

  • Verilerin kontrolü client tarafındadır. Client ihtiyaç duyduğu verileri belirtir. Bu sayede backend tarafından eksik ya da fazla veri gelme durumu önlenmiş olur.
  • GraphQL de tek bir url’e istek atıldığı için ve istek sorgu ile belirlendiği için backend tarafında yapılan herhangi bir versiyonlama client tarafını etkilemez.
  • Bir veri için birden çok api’ye istek atmaya gerek kalmaz. Bu sebeple ağ yoğunluğu daha az olur.
  • Veri kontrolü client tarafında olduğu response tipleri client tarafından bilinir.
  • Backend tarafında yapılan geliştirmelerin dokümanı otomatik olarak oluşturulur.

Dezavantajları:

  • Tüm istekler POST olduğu için ve yapılan istekler tek bir url’e olduğu için url bazlı cache işlemleri için efor artabilir.
  • Atılan isteğin karmaşıklığını client tarafından gelen sorgu belirliyor. Sorgunun karmaşıklığının artması performans kaybına sebep olabilir.
  • Rest tabanlı uygulamalarda statü koduna göre gelen hata yorumlanabilirken GraphQL tarafında dönen her istek 200 statü kodlu olarak dönmektedir.

GraphQL Komponentleri

Önceden tanımlanmış scalar typelar ya da uygulama geliştirme sırasında tanımlanan tipler kullanarak; belirtilen operasyonlar ile backend uygulamasına istekler atılır. Atılan istekler backend tarafında resolverlar ile çözümlenip akışta bulunan işlemlerden sırasıyla geçerek ilgili response client’a döndürülmektedir.

Veri Tipleri

GraphQL 5 tane scalar type’a sahiptir. Int, Float, String, Boolean ve ID. Bunların yanında enumeration ve object type da tanımlanabilir.

Operasyonlar

Bir istek için 3 tip operasyon bulunmaktadır.

  • Query: Veri okumak için kullanılır.(GET isteği)
  • Mutation: Yeni bir veri oluşturmak, güncellemek ya da silmek için kullanılabilir.(POST — PUT — DELETE)
  • Subscription: Query gibi veri okumak için kullanılır. Buradaki avantaj veride herhangi bir değişiklik olduğunda server ile gerçek zamanlı olarak bağlantı kurduğu için veriyi anlık alabilmesidir.

Sorgu

Örnek bir graphQL sorgusu aşağıdaki gibidir:

  • Operasyon tipi query, mutation ya da subscription olabilir.
  • Sorgularımıza spesifik bir isim verebiliriz(HeroNameAndFriends gibi). Bu isimlendirme herhangi bir lojiği etkilemez.
  • İstek atılacak sorgunun input değerleri yukarıdaki gibi parametrik verilebilir ya da direkt eklenebilir.
  • İstek atılan sorgunun adı backend tarafındaki resolver tarafında bulunan method adı ile birebir aynı olmalıdır(hero).
  • Response olarak hangi alanların döneceğine karar verebiliriz(name).

Demo

GraphQL’i kullanmak için basit bir Spring Boot uygulaması oluşturalım. Uygulamamıza aşağıdaki kütüphaneleri ekleyelim.

--graphql'in asıl işini yapan graphql engine'i implement etmek için kullanılır.
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
</dependency>
--graphql tarafında controller diyebilececeğimiz sınıfıları oluşturmak için kullanılır.
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
</dependency>
-- otomatik dokümantasyon oluşturmayı ve api'ye istek atmayı sağlayan bir arayüzü implement etmek için kullanılır.
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
</dependency>

GraphQL sorgularını server tarafında handle etmek için aşağıdaki interfacelerden implement edilmiş sınıflar kullanılır:

  • GraphQLQueryResolver
  • GraphQLMutationResolver
  • GraphQLSubscriptionResolver

Hesap bilgilerini okumak için uygulamaya giriş kısmını ekleyelim:

@Component
@RequiredArgsConstructor
public class AccountQueryResolver implements GraphQLQueryResolver{

private final AccountService accountService;

public AccountResponse getAccountById(Long id) {
return accountService.getAccountById(id);
}
}

Response sınıfımızı oluşturalım:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AccountResponse {

private Long id;

private String name;

private AccountState state;
}
@Getter
public enum AccountState {

ACTIVE,
PASSIVE,
NEEDS_ACTIVATION;

}

Request/response modelinin ve resolver methodlarının birebir aynısı .graphqls dosyasında oluşturulması gerekir.

Request/response ve resolver methodumuzu resources altında bulunan .graphqls dosyasında oluşturalım:

enum AccountState{
ACTIVE,
PASSIVE,
NEEDS_ACTIVATION
}

type AccountResponse{
id : ID!, #! operatorü field'ın null olmayacağını garanti eder.
name: String,
state: AccountState,
}

type Query {
getAccountById(id : Int) : AccountResponse
}

Uygulamayı …./graphiql üzerinden test edebiliriz:

Yalnızca gerekli alanlar için sorgulama yapabiliriz:

Projenin tamamına buradan ulaşabilirsiniz.

Kaynaklar

--

--