GraphQL, bir API sorgulama dili ve sunucusu tarafı çalışma zamanıdır. Facebook tarafından 2012 yılında geliştirildi ve 2015'te halka açıldı. REST API'lerin aksine, GraphQL, client tarafına hangi verinin döneceğini belirleme yeteneği vererek ağ verimliliğini artırır. Birçok farklı dilde sunucu tarafı implementasyonları bulunmaktadır ve Spring Boot da bunlardan biridir.
Java Spring Boot GraphQL API geliştirme ve GraphiQL testleri nasil yapilir, nasil kullan
Haydi Kodlayalim
GraphQL'in Temel Parçaları:
Schema: GraphQL'in en önemli parçalarından biridir. Tüm veri tiplerini, bu tipler arasındaki ilişkileri ve kullanılabilir sorgu/mutasyonları tanımlar.
Query: Bir GraphQL servisinden veri talep etmek için kullanılır.
Mutation: Veriyi değiştirmek için kullanılır, genellikle POST, PUT, PATCH veya DELETE işlemlerini temsil eder.
Resolver: Her alan için bir fonksiyondur ve bu alanın nasıl çözüleceğini belirler.
GraphQL mülakat soruları ve cevapları
Spring Boot ile GraphQL Uygulaması Örneği:
Öncelikle, Spring Boot projesi oluşturmalı ve aşağıdaki GraphQL Java bağımlılıklarını eklemelisiniz:
xml
Copy code
<dependencies>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>
</dependency>
</dependencies>
Bir GraphQL Schema oluşturmalıyız. Bu, src/main/resources klasöründe schema.graphqls adlı bir dosyada yapılabilir:
graphql
Copy code
type Query{
findPersonById(id: ID): Person
}
type Person {
id: ID
name: String
age: Int
}
Ardından, Person model sınıfını ve bir PersonRepository oluşturmalısınız:
java
Copy code
public class Person {
private Long id;
private String name;
private Integer age;
// getters and setters
}
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}
Sonra bir GraphQLQueryResolver oluşturmalıyız. Bu resolver, GraphQL schema'daki sorguların nasıl çözüleceğini belirler:
java
Copy code
@Component
public class PersonQueryResolver implements GraphQLQueryResolver {
private PersonRepository personRepository;
public PersonQueryResolver(PersonRepository personRepository) {
this.personRepository = personRepository;
}
public Person findPersonById(Long id) {
return personRepository.findById(id).orElse(null);
}
}
Şimdi, bir ID ile bir Person sorgulayabiliriz. Bu, bir HTTP POST isteği ile localhost:8080/graphql adresine yapılabilir ve aşağıdaki gibi bir istek gövdesi içerebilir:
json
Copy code
{
"query
Özür dilerim, yanlışlıkla mesajımı tamamlamadan gönderdim. İstek gövdesi aşağıdaki gibi olmalı:
json
Copy code
{
"query": "{findPersonById(id: 1){name, age}}"
}
Bu istek, ID'si 1 olan kişinin adını ve yaşını sorgular.
Veri döndürme ve değiştirme dışında, bir GraphQL API'si hataları yönetme, doğrulama ve otomatik tamamlama gibi diğer önemli özellikler de sunar. Örneğin, bir alanın yanlış bir veri tipi ile döndürülmesi durumunda, GraphQL bunu bir hata olarak işaretler ve hata detaylarını yanıtta döndürür.
Son olarak, GraphQL bir API sorgulama dili olmasının yanı sıra, istemcilerin ihtiyaçlarına göre özelleştirilmiş veri almasını sağlayan bir yapıdır. Bu, verinin gereksiz ağ trafiğini azaltır ve genellikle daha verimli ve hızlı bir uygulama deneyimi sağlar.
Bu örnek basit bir GraphQL uygulamasıdır ve daha karmaşık senaryolar, birden çok tip ve ilişki, karmaşık veri döndürme ve mutasyonlar, hata yönetimi ve yetkilendirme gibi özellikleri içerebilir. Bu özelliklerin her biri, GraphQL'in gücünü ve esnekliğini daha da gösterir ve bir GraphQL API'sinin nasıl tasarlanacağı ve geliştirileceği konusunda daha derin bir anlayış sağlar.
Daha karmaşık bir senaryoyu Spring Boot örnek kodlarıyla yazar mısın?
Tabii ki, bir blog uygulaması için daha karmaşık bir GraphQL senaryosunu inceleyelim. Bu uygulama, blog yazılarını ve bu yazılara ait yorumları yönetir. Öncelikle, bu senaryonun GraphQL şemasını tanımlamalıyız. Bu, src/main/resources/schema.graphqls dosyasında aşağıdaki gibi olabilir:
graphql
Copy code
type Query{
findAllPosts: [Post]
findPostById(id: ID): Post
}
type Mutation{
savePost(post: PostInput): Post
}
input PostInput{
title: String
content: String
author: String
}
type Post{
id: ID
title: String
content: String
author: String
comments: [Comment]
}
type Comment{
id: ID
text: String
post: Post
}
Bu şemada, Query ve Mutation tipleri ile birlikte Post ve Comment tipleri tanımlanmıştır. PostInput tipi, bir Post oluştururken kullanılır.
Ardından, Post ve Comment için model sınıflarını oluşturmalıyız:
java
Copy code
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
private String content;
private String author;
@OneToMany(mappedBy = "post")
private List<Comment> comments;
// getters and setters
}
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String text;
@ManyToOne
@JoinColumn(name = "post_id", nullable = false)
private Post post;
// getters and setters
}
Post ve Comment için repository sınıfları oluşturmalıyız:
java
Copy code
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {
}
Sonra bir GraphQLQueryResolver ve GraphQLMutationResolver oluşturmalıyız:
java
Copy code
@Component
public class PostQueryResolver implements GraphQLQueryResolver {
private PostRepository postRepository;
public PostQueryResolver(PostRepository postRepository) {
this.postRepository = postRepository;
}
public List<Post> findAllPosts() {
return postRepository.findAll();
}
public Post findPostById(Long id) {
return postRepository.findById(id).orElse(null);
}
}
@Component
public class PostMutationResolver implements GraphQLMutationResolver {
private PostRepository postRepository;
public PostMutationResolver(PostRepository postRepository) {
this.postRepository = postRepository;
}
public Post savePost(String title, String content, String author) {
Post post = new Post();
post.setTitle(title);
post.setContent(content);
post.setAuthor(author);
return postRepository.save(post);
}
}
Bu kodlarla birlikte artık GraphQL API'niz üzerinden blog yazıları oluşturabilir, tüm blog yazılarını listeleyebilir ve belirli bir ID'ye sahip bir blog yazısını sorgulayabilirsiniz. Her Post nesnesi, ilişkili Comment nesnelerini içerir.
Bu, GraphQL'in tek bir sorgu içinde ilişkili nesneleri alma yeteneğinin bir örneğidir. Bu senaryoyu daha karmaşık hale getirmek için, yorumları da işlemek için bir GraphQLMutationResolver oluşturabilirsiniz. İşte bir örneği:
java
Copy code
@Component
public class CommentMutationResolver implements GraphQLMutationResolver {
private PostRepository postRepository;
private CommentRepository commentRepository;
public CommentMutationResolver(PostRepository postRepository, CommentRepository commentRepository) {
this.postRepository = postRepository;
this.commentRepository = commentRepository;
}
public Comment saveComment(String text, Long postId) {
Comment comment = new Comment();
comment.setText(text);
Post post = postRepository.findById(postId).orElseThrow(() -> new RuntimeException("Post not found"));
comment.setPost(post);
return commentRepository.save(comment);
}
}
Bu kod ile, bir blog yazısına yorum ekleyebiliriz. GraphQL, birden çok model arasında ilişkiler oluşturma ve yönetme yeteneği sayesinde bu tür karmaşık senaryoları kolayca destekler.
Bu örnek, bir GraphQL API'sini nasıl oluşturacağınız ve Spring Boot ile nasıl entegre edeceğiniz konusunda genel bir bakış sunmaktadır. Daha karmaşık uygulamalar, hata yönetimi, kimlik doğrulama ve yetkilendirme, performans iyileştirmeleri ve diğer özellikler ekleyebilir. Ancak, bu temel yapı, GraphQL ile bir API oluşturmanın ana hatlarını çizmektedir.
Sınırlı sayıda özellik query ettiğimizbir senaryoyu Spring Boot örnek kodlarıyla yazar mısın?
Tabii ki, GraphQL'in en güçlü özelliklerinden biri olan, yalnızca belirli alanları sorgulama yeteneğini ele alalım. Bu durum, kullanıcının yalnızca belirli bir Post'un başlığına ve yazarına ihtiyaç duyduğu, ancak içeriğine veya yorumlarına ihtiyaç duymadığı bir senaryoyu ele alalım.
Öncelikle, daha önceki örnekte oluşturduğumuz Post modeline bakalım:
java
Copy code
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
private String content;
private String author;
@OneToMany(mappedBy = "post")
private List<Comment> comments;
// getters and setters
}
Bu Post modelinde, title, content, author ve comments alanları bulunmaktadır.
GraphQL kullanarak, bir kullanıcı yalnızca title ve author bilgilerine sahip bir Post sorgulayabilir. İşte bu sorgunun nasıl görüneceği:
json
Copy code
{
"query": "{findPostById(id: 1){title, author}}"
}
Bu sorgu, Post'un tamamını yüklemek yerine, yalnızca title ve author alanlarını döndürür. Bu, ağ verimliliğini artırır ve gereksiz verilerin yüklenmesini önler.
GraphQL'in bu yeteneği, Post'un başlığına ve yazarına ihtiyaç duyan bir front-end bileşeni için çok yararlı olabilir. Bu bileşen, gerektiğinde daha fazla ayrıntı istemek için başka bir sorgu yapabilir. Bu, hem sunucu hem de istemci tarafında verimliliği artırır.
Ayrıca, GraphQL sunucuları genellikle bir Post'un comments alanını yüklemek için ayrı bir resolver kullanır. Bu, yalnızca comments alanı sorgulandığında yorumların yüklenmesini sağlar. Bu, veri yüklemesini daha da verimli hale getirir ve yalnızca gerekli olan verinin yüklenmesini sağlar. Bu yaklaşım, "veri yığınları" veya "veri yükleme" olarak bilinir ve GraphQL'in veri verimliliğini daha da artırır.