GraphQL API مع Kotlin: دليل تعليمي خطوة بخطوة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة إلى GraphQL وKotlin

GraphQL هي لغة استعلام لواجهات برمجة التطبيقات (API) تتيح للعملاء تلقي البيانات التي يحتاجونها فقط. على عكس REST، حيث يعيد كل نقطة نهاية بنية ثابتة، توفر GraphQL مرونة: يمكن لاستعلام واحد أن يجمع بيانات من مصادر مختلفة. Kotlin، بدورها، هي لغة حديثة لـ JVM تجمع بين الإيجاز وأمان الأنواع. في هذا البرنامج التعليمي، سننشئ واجهة برمجة تطبيقات GraphQL كاملة الميزات باستخدام Kotlin ومكتبة graphql-kotlin-spring-server.

ستتعلم كيفية إعداد مشروع، تعريف مخطط، كتابة أدوات الحل، واختبار الواجهة البرمجية عبر GraphiQL. هل أنت مستعد؟ هيا بنا!



1. إعداد المشروع

1.1. إنشاء تطبيق Spring Boot

أولاً، لننشئ مشروعاً جديداً على Spring Initializr. اختر:

  • نوع المشروع: Gradle (Kotlin)
  • اللغة: Kotlin
  • Spring Boot: 3.2+
  • الاعتماديات: Spring Web, Spring Boot DevTools

بعد التنزيل، أضف اعتمادية GraphQL إلى ملف build.gradle.kts:

dependencies {    implementation("com.expediagroup:graphql-kotlin-spring-server:7.0.0")    implementation("org.springframework.boot:spring-boot-starter-web")    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")    testImplementation("org.springframework.boot:spring-boot-starter-test")}


1.2. إعداد التطبيق

أنشئ ملف application.yml في المسار src/main/resources:

server:  port: 8080

graphql: packages: - "com.example.graphql.demo"

سيؤدي هذا إلى توجيه Spring Boot لفحص الحزمة com.example.graphql.demo بحثاً عن أدوات الحل والأنواع.



2. تعريف مخطط GraphQL

2.1. إنشاء نموذج البيانات

لننشئ نموذجاً بسيطاً لكتاب ومؤلف. في Kotlin، نستخدم فئات البيانات:

// src/main/kotlin/com/example/graphql/demo/model/Book.ktpackage com.example.graphql.demo.model

data class Book( val id: String, val title: String, val author: Author, val year: Int)

data class Author( val id: String, val name: String, val books: List<Book> = emptyList())


2.2. تعريف المخطط عبر الكود (SDL)

بدلاً من كتابة ملف schema.graphqls، سنستخدم التعليقات التوضيحية @GraphQLDescription و@GraphQLIgnore. تقوم مكتبة graphql-kotlin تلقائياً بتوليد المخطط بناءً على الفئات. لكن للتوضيح، لننشئ ملف schema.graphqls في src/main/resources:

type Query {    books: [Book!]!    book(id: String!): Book    authors: [Author!]!}

type Mutation { addBook(title: String!, authorId: String!, year: Int!): Book!}

type Book { id: String! title: String! author: Author! year: Int!}

type Author { id: String! name: String! books: [Book!]!}


3. تنفيذ أدوات الحل

3.1. خدمة تخزين البيانات

للتبسيط، سنستخدم تخزيناً في الذاكرة:

// src/main/kotlin/com/example/graphql/demo/service/LibraryService.ktpackage com.example.graphql.demo.service

import com.example.graphql.demo.model.Authorimport com.example.graphql.demo.model.Bookimport org.springframework.stereotype.Serviceimport java.util.UUID

@Serviceclass LibraryService { private val authors = mutableListOf( Author(id = "1", name = "George Orwell"), Author(id = "2", name = "Ray Bradbury") )

private val books = mutableListOf( Book(id = "1", title = "1984", author = authors[0], year = 1949), Book(id = "2", title = "Fahrenheit 451", author = authors[1], year = 1953) )

fun getBooks(): List<Book> = books fun getBook(id: String): Book? = books.find { it.id == id } fun getAuthors(): List<Author> = authors fun getAuthor(id: String): Author? = authors.find { it.id == id }

fun addBook(title: String, authorId: String, year: Int): Book { val author = authors.find { it.id == authorId } ?: throw IllegalArgumentException("Author not found") val book = Book(id = UUID.randomUUID().toString(), title = title, author = author, year = year) books.add(book) return book }}


3.2. أداة حل الاستعلامات

أنشئ أداة حل للاستعلامات:

// src/main/kotlin/com/example/graphql/demo/resolver/QueryResolver.ktpackage com.example.graphql.demo.resolver

import com.example.graphql.demo.model.Authorimport com.example.graphql.demo.model.Bookimport com.example.graphql.demo.service.LibraryServiceimport org.springframework.stereotype.Component

@Componentclass QueryResolver(private val libraryService: LibraryService) {

fun books(): List<Book> = libraryService.getBooks()

fun book(id: String): Book? = libraryService.getBook(id)

fun authors(): List<Author> = libraryService.getAuthors()}


3.3. أداة حل الطفرات (Mutations)

أنشئ أداة حل للطفرات:

// src/main/kotlin/com/example/graphql/demo/resolver/MutationResolver.ktpackage com.example.graphql.demo.resolver

import com.example.graphql.demo.model.Bookimport com.example.graphql.demo.service.LibraryServiceimport org.springframework.stereotype.Component

@Componentclass MutationResolver(private val libraryService: LibraryService) {

fun addBook(title: String, authorId: String, year: Int): Book { return libraryService.addBook(title, authorId, year) }}


4. اختبار الواجهة البرمجية

4.1. تشغيل التطبيق

قم بتشغيل التطبيق عبر الفئة الرئيسية أو باستخدام الأمر:

./gradlew bootRun

بعد التشغيل، ستكون نقطة نهاية GraphQL متاحة على http://localhost:8080/graphql، وواجهة GraphiQL على http://localhost:8080/graphiql.



4.2. أمثلة على الاستعلامات

افتح GraphiQL ونفّذ الاستعلامات التالية:

الحصول على جميع الكتب:

query {    books {        id        title        author {            name        }        year    }}

الحصول على كتاب بواسطة المعرف:

query {    book(id: "1") {        title        author {            name        }    }}

إضافة كتاب جديد:

mutation {    addBook(title: "Brave New World", authorId: "1", year: 1932) {        id        title        author {            name        }    }}


الخلاصة

لقد قمنا بإنشاء واجهة برمجة تطبيقات GraphQL كاملة الوظائف باستخدام Kotlin وSpring Boot. في هذا البرنامج التعليمي، غطينا الخطوات الأساسية: إعداد المشروع، تعريف المخطط، تنفيذ أدوات الحل، والاختبار. توفر GraphQL إمكانيات قوية لاسترجاع البيانات بمرونة، وتجعل Kotlin الكود موجزاً وآمناً.

لمزيد من الدراسة، نوصي باستكشاف الاشتراكات (subscriptions)، معالجة الأخطاء، والتكامل مع قواعد البيانات. حظاً موفقاً في تطويرك!

المدونات

توصيات الكتب