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
HotChocolate
yang lebih baru hingga API penggantinya (saat ini sedang dalam proses) selesai. Kami hanya dapat mendukung rilis v13.5.x
dan 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 > < PackageReference Include = " HotChocolate.AspNetCore " Version = " 13.6.0 " /> < 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 memerlukan 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 @extends
External
berlaku di bidang, lihat dokumentasi @external
Key
berlaku pada objek, lihat dokumentasi @key
Provides
bidang yang berlaku, lihat dokumentasi @provides
Requires
penerapan pada bidang, lihat dokumentasi @requires
Arahan Federasi v2 (mencakup semua arahan v1)
ApolloTag
berlaku pada skema, lihat dokumentasi @tag
ApolloAuthenticated
(sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @authenticated
ComposeDirective
(sejak v2.1) berlaku pada skema, lihat dokumentasi @composeDirective
Contact
berlaku pada skema, lihat @contact
penggunaanInaccessible
berlaku pada semua definisi tipe, lihat dokumentasi @inaccessible
InterfaceObject
(sejak v2.3) berlaku pada objek, lihat dokumentasi @interfaceObject
KeyInterface
berlaku pada antarmuka, lihat dokumentasi antarmuka entitas @key
Link
berlaku pada skema, lihat dokumentasi @link
RequiresScopes
(sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @requiresScopes
Shareable
berlaku pada skema, lihat dokumentasi @shareable
Resolusi entitas
Map
berlaku pada parameter metode penyelesai entitas, memungkinkan Anda memetakan argumen kompleks ke nilai representasi yang lebih sederhana, misalnya [Map("foo.bar")] string bar
ReferenceResolver
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 @extends
External
berlaku di bidang, lihat dokumentasi @external
Key(fieldset)
berlaku pada objek, lihat dokumentasi @key
Provides(fieldset)
yang berlaku pada bidang, lihat dokumentasi @provides
Requires(fieldset)
yang berlaku pada bidang, lihat dokumentasi @requires
Arahan Federasi v2 (mencakup semua arahan v1)
ApolloTag
berlaku pada semua definisi tipe, lihat dokumentasi @tag
ApolloAuthenticated
(sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @authenticated
ComposeDirective(name)
(sejak v2.1) berlaku pada skema, lihat dokumentasi @composeDirective
Contact(name, url?, description?)
berlaku pada skema, lihat penggunaan @contact
Inaccessible
berlaku pada semua definisi tipe, lihat dokumentasi @inaccessible
InterfaceObject
(sejak v2.3) berlaku pada objek, lihat dokumentasi @interfaceObject
Key(fieldset)
berlaku pada objek, lihat dokumentasi @key
Link(url, [import]?)
berlaku pada skema, lihat dokumentasi @link
NonResolvableKey(fieldset)
berlaku pada objek, lihat dokumentasi @key
yang tidak dapat diselesaikanRequiresScopes(scopes)
(sejak v2.5) berlaku pada enum, bidang, antarmuka dan objek, dokumentasi @requiresScopes
Shareable
berlaku pada bidang dan objek, lihat dokumentasi @shareable
Resolusi 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 supergraf 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
- +
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 test
Lihat info lebih lanjut di CONTRIBUTING.md.
Setelah Anda menyiapkan cabang lokal, lihat terbitan terbuka kami untuk melihat di mana Anda dapat berkontribusi.
Untuk informasi lebih lanjut tentang cara menghubungi tim untuk masalah keamanan, lihat Kebijakan Keamanan kami.
Perpustakaan ini dilisensikan di bawah The MIT License (MIT).