GraphQL Java — مكتبة خادم لتنفيذ GraphQL API بلغة Java
GraphQL Java هي مكتبة خادم قوية ومرنة لتنفيذ مواصفات GraphQL بلغة Java. تتيح للمطورين إنشاء واجهات API فعالة وآمنة من حيث الأنواع وقابلة للتوسع بسهولة، مما يمنح العملاء القدرة على طلب البيانات الضرورية فقط. المكتبة مدعومة بنشاط من المجتمع وتُستخدم في بيئات الإنتاج من قبل العديد من الشركات الكبرى.
الإمكانيات الرئيسية
- دعم كامل لمواصفات GraphQL — تنفيذ جميع الأنواع والتوجيهات والتحويرات (mutations) والاشتراكات (subscriptions) والأجزاء (fragments).
- نظام أنواع مرن — إمكانية تعريف المخططات إما بناءً على فئات Java (code-first) أو عبر SDL (schema-first).
- دعم مدمج للتوازي (asynchrony) — استخدام
CompletableFutureلمعالجة الطلبات بكفاءة. - DataLoader — أداة مدمجة لحل مشكلة استعلامات N+1 وتحميل البيانات المجمّع.
- أدوات الاختبار — فئات مدمجة لاختبار الوحدات (unit testing) للمخططات والمحللات.
- قابلية التوسع — دعم القيم العددية المخصصة (custom scalars) والتوجيهات وأدوات التحقق.
بنية المكتبة
تتكون المكتبة من عدة مكونات رئيسية:
- GraphQLSchema — كائن يمثل مخطط API.
- DataFetcher — واجهة وظيفية لجلب البيانات (مماثل للمحلل (resolver) في GraphQL).
- TypeResolver — واجهة لحل الأنواع متعددة الأشكال (الواجهات والاتحادات).
- ExecutionStrategy — استراتيجية تنفيذ الاستعلام (افتراضيًا غير متزامنة).
- Instrumentation — آلية لإدخال منطق إضافي (تسجيل، مقاييس).
مثال على الاستخدام
لننظر إلى مثال بسيط لإنشاء خادم GraphQL لإدارة الكتب.
1. تعريف المخطط عبر SDL
// schema.graphqlstype Query { books: [Book] bookById(id: ID!): Book}
type Book { id: ID! title: String! author: String! year: Int}2. إنشاء المحللات
import graphql.schema.DataFetcher;import graphql.schema.DataFetchingEnvironment;
public class BookDataFetcher {
public static DataFetcher<List<Book>> getBooksDataFetcher() { return environment -> { // في التطبيق الحقيقي، سيكون هنا استعلام لقاعدة البيانات return List.of( new Book("1", "1984", "George Orwell", 1949), new Book("2", "Brave New World", "Aldous Huxley", 1932) ); }; }
public static DataFetcher<Book> getBookByIdDataFetcher() { return environment -> { String id = environment.getArgument("id"); // البحث عن الكتاب بواسطة المعرف return findBookById(id); }; }}3. تجميع المخطط وتنفيذ الاستعلام
import graphql.GraphQL;import graphql.schema.GraphQLSchema;import graphql.schema.idl.RuntimeWiring;import graphql.schema.idl.SchemaParser;import graphql.schema.idl.SchemaGenerator;import graphql.schema.idl.TypeDefinitionRegistry;
public class GraphQLExample { public static void main(String[] args) { // تحميل SDL String schema = "type Query { books: [Book] } type Book { id: ID! title: String! }"; SchemaParser schemaParser = new SchemaParser(); TypeDefinitionRegistry typeRegistry = schemaParser.parse(schema);
// إعداد runtime wiring RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() .type("Query", builder -> builder .dataFetcher("books", BookDataFetcher.getBooksDataFetche