HotChocolate.ApolloFederation
. تدعم حزمة ApolloFederation الآن Union v2 بشكل كامل. من أجل تبسيط عمليات التكامل في النظام البيئي لـ HC، قررنا إيقاف هذه الحزمة لصالح دعم حزمة مدمجة واحدة كاملة الميزات.تحذير نظرًا لحدوث تغيير جذري في واجهة برمجة التطبيقات العامة، لا يمكننا دعم الإصدارات الأحدث من
HotChocolate
حتى تكتمل واجهة برمجة التطبيقات البديلة الخاصة بها (العمل حاليًا قيد التقدم). يمكننا فقط دعم الإصدارات v13.5.x
وv13.6.x
يعد Apollo Union عبارة عن بنية قوية ومفتوحة تساعدك على إنشاء رسم بياني فائق موحد يجمع بين واجهات برمجة تطبيقات GraphQL المتعددة. يوفر ApolloGraphQL.HotChocolate.Federation
دعم اتحاد Apollo لإنشاء رسوم بيانية فرعية في نظام HotChocolate
البيئي. يمكن تشغيل الرسوم البيانية الفرعية الفردية بشكل مستقل عن بعضها البعض، ولكن يمكن أيضًا تحديد العلاقات مع الرسوم البيانية الفرعية الأخرى باستخدام التوجيهات الموحدة. راجع وثائق اتحاد أبولو للحصول على التفاصيل.
تم نشر حزمة ApolloGraphQL.HotChocolate.Federation
إلى Nuget. قم بتحديث ملف .csproj
الخاص بك بمراجع الحزمة التالية
< ItemGroup > < PackageReference Include = " HotChocolate.AspNetCore " Version = " 13.6.0 " /> < PackageReference Include = " ApolloGraphQL.HotChocolate.Federation " Version = " $LatestVersion " /> ItemGroup >
بعد تثبيت الحزم اللازمة، تحتاج إلى تسجيل Apollo Union في خدمة GraphQL الخاصة بك.
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( )
// register your types and services
;
var app = builder . Build ( ) ;
app . MapGraphQL ( ) ;
app . Run ( ) ;
إذا كنت ترغب في الاشتراك في مخطط الاتحاد v1، فستحتاج إلى استخدام ملحق
.AddApolloFederation()
بدلاً من ذلك.
ارجع إلى وثائق HotChocolate
للحصول على معلومات تفصيلية حول كيفية إنشاء مخططات GraphQL وتكوين الخادم الخاص بك.
يتطلب اتحاد أبولو من الرسوم البيانية الفرعية توفير بعض البيانات الوصفية الإضافية لجعلها على علم بالرسم البياني الفائق. الكيانات هي كائنات GraphQL التي يمكن تعريفها بشكل فريد عبر الرسم البياني الفائق بواسطة @key
s المحدد. نظرًا لأنه يمكن توسيع الكيانات من خلال رسوم بيانية فرعية مختلفة، فإننا نحتاج إلى نقطة دخول إضافية للوصول إلى الكيانات، أي أن الرسوم البيانية الفرعية تحتاج إلى تنفيذ وحدات الحل المرجعية للكيانات التي تدعمها.
راجع وثائق أبولو للحصول على تفاصيل إضافية عن الاتحاد.
يتم توفير جميع التوجيهات الموحدة كسمات يمكن تطبيقها مباشرة على الفئات/الحقول/الطرق.
[ Key ( " id " ) ]
public class Product
{
public Product ( string id , string name , string ? description )
{
Id = id ;
Name = name ;
Description = description ;
}
[ ID ]
public string Id { get ; }
public string Name { get ; }
public string ? Description { get ; }
// assumes ProductRepository with GetById method exists
// reference resolver method must be public static
[ ReferenceResolver ]
public static Product GetByIdAsync (
string id ,
ProductRepository productRepository )
=> productRepository . GetById ( id ) ;
}
سيؤدي هذا إلى إنشاء النوع التالي
type Product @key ( fields : " id " ) {
id : ID !
name : String !
description : String
}
توجيهات الاتحاد v1
Extends
تطبيقه على الكائنات، راجع وثائق @extends
External
على الحقول، راجع الوثائق @external
Key
المطبق على الكائنات، راجع وثائق @key
Provides
على الحقول، راجع @provides
الوثائقRequires
التطبيق في الحقول، راجع @requires
الوثائقتوجيهات الاتحاد v2 (تتضمن جميع توجيهات v1)
ApolloTag
قابل للتطبيق على المخطط، راجع وثائق @tag
ApolloAuthenticated
(منذ الإصدار 2.5) ينطبق على التعداد والحقل والواجهة والكائن ووثائق @authenticated
ComposeDirective
(منذ الإصدار 2.1) المطبق على المخطط، راجع وثائق @composeDirective
Contact
المطبقة على المخطط، راجع استخدام @contact
Inaccessible
على كافة تعريفات الأنواع، راجع وثائق @inaccessible
InterfaceObject
(منذ الإصدار 2.3) ينطبق على الكائنات، راجع وثائق @interfaceObject
KeyInterface
قابل للتطبيق على الواجهات، راجع وثائق @key
لواجهة الكيانLink
المطبق على المخطط، راجع وثائق @link
RequiresScopes
(منذ الإصدار 2.5) ينطبق على التعداد والحقل والواجهة والكائن، وثائق @requiresScopes
Shareable
وقابل للتطبيق على المخطط، راجع وثائق @shareable
قرار الكيان
Map
قابلة للتطبيق على معلمات أسلوب محلل الكيان، تسمح لك بتعيين وسيطة معقدة لقيمة تمثيل أبسط، على سبيل المثال [Map("foo.bar")] string bar
ReferenceResolver
ينطبق على الطرق الثابتة العامة داخل فئة الكيان للإشارة إلى محلل الكيانوبدلاً من ذلك، إذا كنت بحاجة إلى مزيد من التحكم الدقيق، يمكنك استخدام النهج الأول للتعليمات البرمجية وملء معلومات الاتحاد يدويًا في واصف نوع GraphQL الأساسي. تعرض جميع التوجيهات الموحدة الأساليب المقابلة في الواصف المطبق.
public class Product
{
public Product ( string id , string name , string ? description )
{
Id = id ;
Name = name ;
Description = description ;
}
[ ID ]
public string Id { get ; }
public string Name { get ; }
public string ? Description { get ; }
}
public class ProductType : ObjectType < Product >
{
protected override void Configure ( IObjectTypeDescriptor < Product > descriptor )
{
descriptor
. Key ( " id " )
. ResolveReferenceWith ( t => GetProduct ( default ! , default ! ) ) ;
}
private static Product GetProduct (
string id ,
ProductRepository productRepository )
=> productRepository . GetById ( upc ) ;
}
سيؤدي هذا إلى إنشاء النوع التالي
type Product @key ( fields : " id " ) {
id : ID !
name : String !
description : String
}
توجيهات الاتحاد v1
ExtendsType
على الكائنات، راجع وثائق @extends
External
على الحقول، راجع الوثائق @external
Key(fieldset)
المطبق على الكائنات، راجع وثائق @key
Provides(fieldset)
على الحقول، راجع وثائق @provides
Requires(fieldset)
المطبقة على الحقول، راجع @requires
الوثائقتوجيهات الاتحاد v2 (تتضمن جميع توجيهات v1)
ApolloTag
على جميع تعريفات الأنواع، راجع وثائق @tag
ApolloAuthenticated
(منذ الإصدار 2.5) ينطبق على التعداد والحقل والواجهة والكائن ووثائق @authenticated
ComposeDirective(name)
(منذ الإصدار 2.1) المطبق على المخطط، راجع وثائق @composeDirective
Contact(name, url?, description?)
المطبقة على المخطط، راجع استخدام @contact
Inaccessible
على كافة تعريفات الأنواع، راجع وثائق @inaccessible
InterfaceObject
(منذ الإصدار 2.3) ينطبق على الكائنات، راجع وثائق @interfaceObject
Key(fieldset)
المطبق على الكائنات، راجع وثائق @key
Link(url, [import]?)
المطبق على المخطط، راجع وثائق @link
NonResolvableKey(fieldset)
المطبق على الكائنات، راجع وثائق @key
غير القابلة للحلRequiresScopes(scopes)
(منذ الإصدار 2.5) ينطبق على التعداد والحقل والواجهة والكائن، وثائق @requiresScopes
Shareable
على الحقول والكائنات، راجع وثائق @shareable
قرار الكيان
ResolveReferenceWith
لتتمكن من حل الكيانات راجع وثائق HotChocolate للحصول على تفاصيل حول دعم الخادم لواجهة سطر الأوامر. من أجل إنشاء المخطط في وقت الإنشاء، تحتاج إلى إضافة اعتمادية إضافية على حزمة HotChocolate.AspNetCore.CommandLine
وتكوين الخادم الخاص بك للسماح له بـ RunWithGraphQLCommands
.
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( )
// register your types and services
;
var app = builder . Build ( ) ;
app . MapGraphQL ( ) ;
app . RunWithGraphQLCommands ( args ) ;
يمكنك بعد ذلك إنشاء المخطط الخاص بك عن طريق التشغيل
dotnet run -- schema export --output schema.graphql
افتراضيًا، سيقوم ApolloGraphQL.HotChocolate.Federation
بإنشاء المخطط باستخدام أحدث إصدار معتمد من الاتحاد. إذا كنت ترغب في الاشتراك في استخدام الإصدارات الأقدم، فيمكنك ذلك عن طريق تحديد الإصدار عند تكوين ملحق AddApolloFederationV2
.
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( FederationVersion . FEDERATION_23 )
// register your types and services
;
وبدلاً من ذلك، يمكنك أيضًا توفير FederatedSchema
المخصص الذي يستهدف إصدار اتحاد محدد
public class CustomSchema : FederatedSchema
{
public CustomSchema ( ) : base ( FederationVersion . FEDERATION_23 ) {
}
}
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( new CustomSchema ( ) )
// register your types and services
;
إذا كنت ترغب في تخصيص مخططك من خلال تطبيق بعض التوجيهات، فيمكنك أيضًا توفير FederatedSchema
مخصص يمكن إضافة تعليقات توضيحية إليه باستخدام السمات التي تعمل على توسيع SchemaTypeDescriptorAttribute
[ AttributeUsage ( AttributeTargets . Class | AttributeTargets . Struct , Inherited = true , AllowMultiple = true ) ]
public sealed class CustomAttribute : SchemaTypeDescriptorAttribute
{
public override void OnConfigure ( IDescriptorContext context , ISchemaTypeDescriptor descriptor , Type type )
{
// configure your directive here
}
}
[ Custom ]
public class CustomSchema : FederatedSchema
{
public CustomSchema ( ) : base ( FederationVersion . FEDERATION_23 ) {
}
}
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( new CustomSchema ( ) )
// register your types and services
;
وبدلاً من ذلك، يمكنك أيضًا تحديد إجراء تكوين المخطط المخصص عند إنشاء رسم بياني فرعي متحد
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( schemaConfiguration : s =>
{
// apply your directive here
} )
// register your types and services
;
@key
غير قابل للحل يمكن أن تستخدم الرسوم البيانية الفرعية الخاصة بك كيانًا كنوع إرجاع للحقل دون المساهمة بأي حقول في هذا الكيان. نظرًا لأننا لا نزال بحاجة إلى تعريف النوع لإنشاء مخطط صالح، فيمكننا تعريف كائن كعب الروتين باستخدام [NonResolvableKeyAttribute]
.
public class Review {
public Review ( Product product , int score )
{
Product = product ;
Score = score
}
public Product Product { get ; }
public int Score { get ; }
}
[ NonResolvableKey ( " id " ) ]
public class Product {
public Product ( string id )
{
Id = id ;
}
public string Id { get ; }
}
@composedDirective
الاستخدام افتراضيًا، يستبعد مخطط Supergraph كافة التوجيهات المخصصة. يتم استخدام @composeDirective
لتحديد التوجيهات المخصصة التي يجب الحفاظ عليها في مخطط Supergraph.
يوفر ApolloGraphQL.HotChocolate.Federation
فئة FederatedSchema
الشائعة التي تطبق تلقائيًا تعريف Apollo Union v2 @link
. عند تطبيق أي توجيهات مخطط مخصصة، يجب عليك توسيع هذه الفئة وإضافة السمات/التوجيهات المطلوبة.
عند تطبيق @composedDirective
فإنك تحتاج أيضًا إلى @link
بمواصفاتك. يجب بعد ذلك تمرير مخططك المخصص إلى ملحق AddApolloFederationV2
.
[ ComposeDirective ( " @custom " ) ]
[ Link ( " https://myspecs.dev/myCustomDirective/v1.0 " , new string [ ] { " @custom " } ) ]
public class CustomSchema : FederatedSchema
{
}
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( new CustomSchema ( ) )
// register your types and services
;
وبدلاً من ذلك، يمكنك تطبيق @composedDirective
عن طريق تطبيقه مباشرةً على مخطط مستهدف باستخدام إجراء التكوين
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( schemaConfiguration : s =>
{
s . Link ( " https://myspecs.dev/myCustomDirective/v1.0 " , new string [ ] { " @custom " } ) ;
s . ComposeDirective ( " @custom " ) ;
} )
// register your types and services
;
@interfaceObject
الاستخداميدعم Apollo Union v2 واجهات الكيانات ، وهو امتداد قوي لواجهات GraphQL التي تسمح لك بتوسيع وظائف الواجهة عبر الرسم البياني الفائق دون الحاجة إلى تنفيذ (أو حتى إدراك) جميع أنواع التنفيذ الخاصة بها.
في الرسم البياني الفرعي الذي يحدد الواجهة، نحتاج إلى تطبيق @key
[ InterfaceType ]
[ KeyInterface ( " id " ) ]
public interface Product
{
[ ID ]
string Id { get ; }
string Name { get ; }
}
[ Key ( " id " ) ]
public class Book : Product
{
[ ID ]
public string Id { get ; set ; }
public string Name { get ; set ; }
public string Content { get ; set ; }
}
يمكننا بعد ذلك توسيع الواجهة في رسم بياني فرعي آخر عن طريق جعلها نوعًا وتطبيق @interfaceObject
ونفس توجيه @key
. يتيح لك ذلك إضافة حقول جديدة إلى كل كيان يقوم بتنفيذ الواجهة الخاصة بك (على سبيل المثال، إضافة حقل Reviews
إلى جميع عمليات تنفيذ Product
).
[ Key ( " id " ) ]
[ InterfaceObject ]
public class Product
{
[ ID ]
public string Id { get ; set ; }
public List < string > Reviews { get ; set ; }
}
يتم استخدام التوجيه @requiresScopes
للإشارة إلى أن العنصر الهدف لا يمكن الوصول إليه إلا لمستخدمي الرسم البياني الفائق المصادق عليهم باستخدام نطاقات JWT المناسبة. راجع مقالة Apollo Router للحصول على تفاصيل إضافية.
public class Query
{
[ RequiresScopes ( scopes : new string [ ] { " scope1, scope2 " , " scope3 " } ) ]
[ RequiresScopes ( scopes : new string [ ] { " scope4 " } ) ]
public Product ? GetProduct ( [ ID ] string id , Data repository )
=> repository . Products . FirstOrDefault ( t => t . Id . Equals ( id ) ) ;
}
سيؤدي هذا إلى إنشاء المخطط التالي
type Query {
product ( id : ID ! ): Product @requiresScopes ( scopes : [ [ " scope1, scope2 " , " scope3 " ], [ " scope4 " ] ])
}
يمكنك استخدام توجيه @contact
لإضافة معلومات الاتصال الخاصة بفريقك إلى مخطط الرسم البياني الفرعي. يتم عرض هذه المعلومات في الاستوديو، مما يساعد الفرق الأخرى على معرفة من يجب الاتصال به للحصول على المساعدة في الرسم البياني الفرعي. انظر الوثائق للحصول على التفاصيل.
نحتاج إلى تطبيق سمة [Contact]
على المخطط. يمكنك إما تطبيق سمة [Contact]
على مخطط مخصص وتمرير مخططك المخصص إلى ملحق AddApolloFederationV2
.
[ Contact ( " MyTeamName " , " https://myteam.slack.com/archives/teams-chat-room-url " , " send urgent issues to [#oncall](https://yourteam.slack.com/archives/oncall) " ) ]
public class CustomSchema : FederatedSchema
{
}
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddType < ContactDirectiveType > ( ) ;
. AddApolloFederationV2 ( new CustomSchema ( ) )
// register your types and services
;
أو قم بتطبيق توجيه @contact
مباشرة على المخطط من خلال توفير إجراء تكوين المخطط المخصص
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( schemaConfiguration : s =>
{
s . Contact ( " MyTeamName " , " https://myteam.slack.com/archives/teams-chat-room-url " , " send urgent issues to [#oncall](https://yourteam.slack.com/archives/oncall) " ) ;
} )
// register your types and services
;
يتم تعيين ApolloGraphQL.HotChocolate.Federation
تلقائيًا لاستخدام اسم نوع Query
. عند استخدام أنواع عمليات Query
الجذري المخصصة، يتعين عليك تكوين المخطط بشكل صريح باستخدام تلك القيم المخصصة.
public class CustomQuery
{
public Foo ? GetFoo ( [ ID ] string id , Data repository )
=> repository . Foos . FirstOrDefault ( t => t . Id . Equals ( id ) ) ;
}
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. ModifyOptions ( opts => opts . QueryTypeName = " CustomQuery " )
. AddApolloFederationV2 ( )
. AddQueryType < CustomQuery > ( )
// register your other types and services
;
var app = builder . Build ( ) ;
app . MapGraphQL ( ) ;
app . Run ( ) ;
يعد الترحيل من HotChocolate.Federation
إلى ApolloGraphQL.HotChocolate.Federation
أمرًا سهلاً. ما عليك سوى تحديث استيراد الحزمة الخاصة بك للإشارة إلى وحدة نمطية جديدة
- +
وتحديث واردات مساحة الاسم
- using HotChocolate.ApolloFederation;
+ using ApolloGraphQL.HotChocolate.Federation;
بينما كنا نحاول أن نجعل عملية الترحيل سلسة قدر الإمكان، كان علينا إجراء بعض التعديلات على المكتبة. نظرًا للاعتماد على بعض واجهات برمجة التطبيقات الداخلية، كان علينا إجراء التغييرات العاجلة التالية على المكتبة:
[Key]
ينطبق الآن فقط على الفئات ولم يعد بإمكانك تطبيقه على الحقول الفردية[ReferenceResolver]
ينطبق الآن فقط على الأساليب الثابتة العامة داخل الكيان ، ولم يعد قابلاً للتطبيق على الفئات يمكن لـ [EntityResolver]
تعيين تمثيل الكيان تلقائيًا إلى قيم @key
/ @requires
المدعومة. يتم تعيين حقول Scalars @key
تلقائيًا ويمكننا استخدام سمة [Map]
لتعيين القيم العددية تلقائيًا من مجموعات التحديد المعقدة.
لا ندعم حاليًا التعيين التلقائي لقيم القائمة والكائنات.
كحل مؤقت، تحتاج إلى تحليل كائن التمثيل يدويًا في التنفيذ الخاص بك.
[ ReferenceResolver ]
public static Foo GetByFooBar (
[ LocalState ] ObjectValueNode data
Data repository )
{
// TODO implement logic here by manually reading values from local state data
}
@link
محدودحاليًا، ندعم فقط استيراد العناصر من الرسوم البيانية الفرعية المشار إليها.
مسافة الاسم وإعادة تسمية العناصر غير مدعومة حاليًا. انظر المشكلة للحصول على التفاصيل.
إذا كان لديك سؤال محدد حول المكتبة أو الكود، يرجى بدء مناقشة في منتديات مجتمع Apollo أو بدء محادثة على خادم Discord الخاص بنا.
للبدء، يرجى تفرع الريبو والخروج من فرع جديد. يمكنك بعد ذلك إنشاء المكتبة محليًا عن طريق التشغيل
# install dependencies
dotnet restore
# build project
dotnet build
# run tests
dotnet test
انظر المزيد من المعلومات في CONTRIBUTING.md.
بعد الانتهاء من إعداد فرعك المحلي، قم بإلقاء نظرة على مشكلاتنا المفتوحة لمعرفة أين يمكنك المساهمة.
لمزيد من المعلومات حول كيفية الاتصال بالفريق بشأن المشكلات الأمنية، راجع سياسة الأمان الخاصة بنا.
هذه المكتبة مرخصة بموجب ترخيص معهد ماساتشوستس للتكنولوجيا (MIT).