HotChocolate.ApolloFederation sekarang sepenuhnya mendukung Federation v2. Untuk menyederhanakan integrasi dalam ekosistem HC, kami memutuskan untuk tidak lagi menggunakan paket ini dan hanya mendukung satu paket bawaan berfitur lengkap.Peringatan Karena perubahan yang dapat menyebabkan gangguan pada API publik, kami tidak dapat mendukung versi
HotChocolateyang lebih baru hingga API penggantinya (saat ini sedang dalam proses) selesai. Kami hanya dapat mendukung rilis v13.5.xdan v13.6.x
Apollo Federation adalah arsitektur terbuka dan kuat yang membantu Anda membuat supergraf terpadu yang menggabungkan beberapa API GraphQL. ApolloGraphQL.HotChocolate.Federation memberikan dukungan Apollo Federation untuk membangun subgraf di ekosistem HotChocolate . Subgraf individual dapat dijalankan secara independen satu sama lain tetapi juga dapat menentukan hubungan ke subgraf lainnya dengan menggunakan arahan Federasi. Lihat dokumentasi Federasi Apollo untuk detailnya.
Paket ApolloGraphQL.HotChocolate.Federation diterbitkan ke Nuget. Perbarui file .csproj Anda dengan referensi paket berikut
< ItemGroup >
<!-- make sure to also include HotChocolate package -->
< PackageReference Include = " HotChocolate.AspNetCore " Version = " 13.6.0 " />
<!-- federation package -->
< PackageReference Include = " ApolloGraphQL.HotChocolate.Federation " Version = " $LatestVersion " />
</ ItemGroup >Setelah menginstal paket yang diperlukan, Anda perlu mendaftarkan Apollo Federation dengan layanan GraphQL Anda.
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( )
// register your types and services
;
var app = builder . Build ( ) ;
app . MapGraphQL ( ) ;
app . Run ( ) ;Jika Anda ingin ikut serta dalam skema Federasi v1, Anda perlu menggunakan ekstensi
.AddApolloFederation()sebagai gantinya.
Lihat dokumentasi HotChocolate untuk informasi detail tentang cara membuat skema GraphQL dan mengonfigurasi server Anda.
Federasi Apollo mengharuskan subgraf untuk menyediakan beberapa metadata tambahan agar mereka sadar akan supergraf. Entitas adalah objek GraphQL yang dapat diidentifikasi secara unik di seluruh supergraf dengan @key yang ditentukan. Karena entitas dapat diperluas dengan berbagai subgraf, kita memerlukan titik masuk tambahan untuk mengakses entitas, yaitu subgraf perlu menerapkan penyelesai referensi untuk entitas yang didukungnya.
Lihat dokumentasi Apollo untuk rincian Federasi tambahan.
Semua arahan gabungan disediakan sebagai atribut yang dapat diterapkan langsung pada kelas/bidang/metode.
[ 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 ) ;
}Ini akan menghasilkan tipe berikut
type Product @key ( fields : " id " ) {
id : ID !
name : String !
description : String
}Arahan Federasi v1
Extends yang berlaku pada objek, lihat dokumentasi @extendsExternal berlaku di bidang, lihat dokumentasi @externalKey berlaku pada objek, lihat dokumentasi @keyProvides bidang yang berlaku, lihat dokumentasi @providesRequires penerapan pada bidang, lihat dokumentasi @requiresArahan Federasi v2 (mencakup semua arahan v1)
ApolloTag berlaku pada skema, lihat dokumentasi @tagApolloAuthenticated (sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @authenticatedComposeDirective (sejak v2.1) berlaku pada skema, lihat dokumentasi @composeDirectiveContact berlaku pada skema, lihat @contact penggunaanInaccessible berlaku pada semua definisi tipe, lihat dokumentasi @inaccessibleInterfaceObject (sejak v2.3) berlaku pada objek, lihat dokumentasi @interfaceObjectKeyInterface berlaku pada antarmuka, lihat dokumentasi antarmuka entitas @keyLink berlaku pada skema, lihat dokumentasi @linkRequiresScopes (sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @requiresScopesShareable berlaku pada skema, lihat dokumentasi @shareableResolusi entitas
Map berlaku pada parameter metode penyelesai entitas, memungkinkan Anda memetakan argumen kompleks ke nilai representasi yang lebih sederhana, misalnya [Map("foo.bar")] string barReferenceResolver berlaku pada metode statis publik dalam kelas entitas untuk menunjukkan penyelesai entitasAlternatifnya, jika Anda memerlukan kontrol yang lebih terperinci, Anda dapat menggunakan pendekatan kode pertama dan secara manual mengisi informasi federasi pada deskriptor tipe GraphQL yang mendasarinya. Semua arahan gabungan memaparkan metode yang sesuai pada deskriptor yang berlaku.
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 ) ;
}Ini akan menghasilkan tipe berikut
type Product @key ( fields : " id " ) {
id : ID !
name : String !
description : String
}Arahan Federasi v1
ExtendsType berlaku pada objek, lihat dokumentasi @extendsExternal berlaku di bidang, lihat dokumentasi @externalKey(fieldset) berlaku pada objek, lihat dokumentasi @keyProvides(fieldset) yang berlaku pada bidang, lihat dokumentasi @providesRequires(fieldset) yang berlaku pada bidang, lihat dokumentasi @requiresArahan Federasi v2 (mencakup semua arahan v1)
ApolloTag berlaku pada semua definisi tipe, lihat dokumentasi @tagApolloAuthenticated (sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @authenticatedComposeDirective(name) (sejak v2.1) berlaku pada skema, lihat dokumentasi @composeDirectiveContact(name, url?, description?) berlaku pada skema, lihat penggunaan @contactInaccessible berlaku pada semua definisi tipe, lihat dokumentasi @inaccessibleInterfaceObject (sejak v2.3) berlaku pada objek, lihat dokumentasi @interfaceObjectKey(fieldset) berlaku pada objek, lihat dokumentasi @keyLink(url, [import]?) berlaku pada skema, lihat dokumentasi @linkNonResolvableKey(fieldset) berlaku pada objek, lihat dokumentasi @key yang tidak dapat diselesaikanRequiresScopes(scopes) (sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @requiresScopesShareable berlaku pada bidang dan objek, lihat dokumentasi @shareableResolusi entitas
ResolveReferenceWith untuk dapat menyelesaikan entitas Lihat dokumentasi HotChocolate untuk detail tentang dukungan server untuk antarmuka baris perintah. Untuk menghasilkan skema pada waktu pembuatan, Anda perlu menambahkan ketergantungan tambahan pada paket HotChocolate.AspNetCore.CommandLine dan mengonfigurasi server Anda agar mengizinkannya RunWithGraphQLCommands .
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( )
// register your types and services
;
var app = builder . Build ( ) ;
app . MapGraphQL ( ) ;
app . RunWithGraphQLCommands ( args ) ;Anda kemudian dapat membuat skema dengan menjalankan
dotnet run -- schema export --output schema.graphql Secara default, ApolloGraphQL.HotChocolate.Federation akan menghasilkan skema menggunakan versi Federasi terbaru yang didukung. Jika Anda ingin ikut serta menggunakan versi yang lebih lama, Anda dapat melakukannya dengan menentukan versi saat mengonfigurasi ekstensi AddApolloFederationV2 .
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( FederationVersion . FEDERATION_23 )
// register your types and services
; Alternatifnya, Anda juga dapat menyediakan FederatedSchema khusus yang menargetkan versi Federasi tertentu
public class CustomSchema : FederatedSchema
{
public CustomSchema ( ) : base ( FederationVersion . FEDERATION_23 ) {
}
}
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( new CustomSchema ( ) )
// register your types and services
; Jika Anda ingin menyesuaikan skema Anda dengan menerapkan beberapa arahan, Anda juga dapat menyediakan FederatedSchema khusus yang dapat dianotasi dengan atribut yang memperluas 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
;Alternatifnya, Anda juga dapat menentukan tindakan konfigurasi skema kustom saat membuat subgraf gabungan
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( schemaConfiguration : s =>
{
// apply your directive here
} )
// register your types and services
; @key yang tidak dapat diselesaikan Subgraf Anda dapat menggunakan entitas sebagai tipe kembalian bidang tanpa menyumbangkan bidang apa pun ke entitas tersebut. Karena kita masih memerlukan definisi tipe untuk menghasilkan skema yang valid, kita dapat mendefinisikan objek stub dengan [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 penggunaan Secara default, skema Supergraph mengecualikan semua arahan khusus. @composeDirective digunakan untuk menentukan arahan khusus yang harus dipertahankan dalam skema Supergraph.
ApolloGraphQL.HotChocolate.Federation menyediakan kelas FederatedSchema umum yang secara otomatis menerapkan definisi Apollo Federation v2 @link . Saat menerapkan arahan skema khusus apa pun, Anda harus memperluas kelas ini dan menambahkan atribut/arahan yang diperlukan.
Saat menerapkan @composedDirective Anda juga perlu @link sesuai spesifikasi Anda. Skema khusus Anda kemudian harus diteruskan ke ekstensi 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
; Alternatifnya, Anda dapat menerapkan @composedDirective dengan langsung menerapkannya pada skema target menggunakan tindakan konfigurasi
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 penggunaanApollo Federation v2 mendukung antarmuka entitas , ekstensi kuat untuk antarmuka GraphQL yang memungkinkan Anda memperluas fungsionalitas antarmuka di seluruh supergraph tanpa harus mengimplementasikan (atau bahkan menyadari) semua jenis penerapannya.
Dalam subgraf yang mendefinisikan antarmuka kita perlu menerapkan @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 ; }
} Kita kemudian dapat memperluas antarmuka di subgraf lain dengan menjadikannya sebuah tipe, menerapkan @interfaceObject dan direktif @key yang sama. Hal ini memungkinkan Anda menambahkan kolom baru ke setiap entitas yang mengimplementasikan antarmuka Anda (misalnya menambahkan kolom Reviews ke semua implementasi Product ).
[ Key ( " id " ) ]
[ InterfaceObject ]
public class Product
{
[ ID ]
public string Id { get ; set ; }
public List < string > Reviews { get ; set ; }
} Arahan @requiresScopes digunakan untuk menunjukkan bahwa elemen target hanya dapat diakses oleh pengguna supergraph yang diautentikasi dengan cakupan JWT yang sesuai. Lihat artikel Apollo Router untuk detail tambahan.
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 ) ) ;
}Ini akan menghasilkan skema berikut
type Query {
product ( id : ID ! ): Product @requiresScopes ( scopes : [ [ " scope1, scope2 " , " scope3 " ], [ " scope4 " ] ])
} Anda dapat menggunakan arahan @contact untuk menambahkan informasi kontak tim Anda ke skema subgraf. Informasi ini ditampilkan di Studio, yang membantu tim lain mengetahui siapa yang harus dihubungi untuk mendapatkan bantuan terkait subgraf. Lihat dokumentasi untuk detailnya.
Kita perlu menerapkan atribut [Contact] pada skema. Anda dapat menerapkan atribut [Contact] pada skema khusus dan meneruskan skema khusus Anda ke ekstensi 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
; atau terapkan arahan @contact secara langsung pada skema dengan memberikan tindakan konfigurasi skema khusus
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 secara otomatis menggunakan nama jenis Query secara default. Saat menggunakan jenis operasi Query root khusus, Anda harus mengonfigurasi skema secara eksplisit dengan nilai khusus tersebut.
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 ( ) ; Bermigrasi dari HotChocolate.Federation ke ApolloGraphQL.HotChocolate.Federation itu mudah. Cukup perbarui impor paket Anda untuk menunjuk ke modul baru
<ItemGroup>
<!-- make sure to also include HotChocolate package -->
<PackageReference Include="HotChocolate.AspNetCore" Version="13.6.0" />
<!-- federation package -->
- <PackageReference Include="HotChocolate.ApolloFederation" Version="$LatestVersion" />
+ <PackageReference Include="ApolloGraphQL.HotChocolate.Federation" Version="$LatestVersion" />
</ItemGroup>dan perbarui impor namespace
- using HotChocolate.ApolloFederation;
+ using ApolloGraphQL.HotChocolate.Federation;Meskipun kami mencoba membuat proses migrasi selancar mungkin, kami harus melakukan beberapa penyesuaian pada perpustakaan. Karena ketergantungan pada beberapa API internal, kami harus membuat perubahan berikut pada perpustakaan:
[Key] sekarang hanya berlaku di kelas dan Anda tidak lagi dapat menerapkannya di bidang individual[ReferenceResolver] sekarang hanya berlaku pada metode statis publik dalam suatu entitas , tidak lagi berlaku di kelas [EntityResolver] s dapat secara otomatis memetakan representasi entitas ke nilai @key / @requires yang didukung. Bidang skalar @key secara otomatis dipetakan dan kita dapat menggunakan atribut [Map] untuk memetakan nilai skalar secara otomatis dari kumpulan pilihan yang kompleks.
Saat ini kami tidak mendukung pemetaan otomatis nilai Daftar dan Objek.
Sebagai solusinya, Anda perlu mengurai objek representasi secara manual dalam implementasi Anda.
[ ReferenceResolver ]
public static Foo GetByFooBar (
[ LocalState ] ObjectValueNode data
Data repository )
{
// TODO implement logic here by manually reading values from local state data
} @link terbatasSaat ini kami hanya mendukung pengimporan elemen dari subgraf yang direferensikan.
Penspasian nama dan penggantian nama elemen saat ini tidak didukung. Lihat masalah untuk detailnya.
Jika Anda memiliki pertanyaan spesifik tentang perpustakaan atau kode, silakan mulai diskusi di forum komunitas Apollo atau mulai percakapan di server Discord kami.
Untuk memulai, silakan fork repo dan checkout cabang baru. Anda kemudian dapat membangun perpustakaan secara lokal dengan menjalankan
# install dependencies
dotnet restore
# build project
dotnet build
# run tests
dotnet testLihat info lebih lanjut di CONTRIBUTING.md.
Setelah Anda menyiapkan cabang lokal, lihat terbitan terbuka kami untuk mengetahui di mana Anda dapat berkontribusi.
Untuk informasi lebih lanjut tentang cara menghubungi tim untuk masalah keamanan, lihat Kebijakan Keamanan kami.