HotChocolate.ApolloFederation
패키지는 이제 Federation v2를 완벽하게 지원합니다. HC 생태계의 통합을 단순화하기 위해 우리는 모든 기능을 갖춘 단일 내장 패키지를 지원하기 위해 이 패키지를 더 이상 사용하지 않기로 결정했습니다.경고 공개 API의 주요 변경으로 인해 대체 API(현재 작업 진행 중)가 완료될 때까지
HotChocolate
의 최신 버전을 지원할 수 없습니다. v13.5.x
및 v13.6.x
릴리스만 지원할 수 있습니다 .
Apollo Federation 은 여러 GraphQL API를 결합하는 통합 슈퍼 그래프를 생성하는 데 도움이 되는 강력한 개방형 아키텍처입니다. ApolloGraphQL.HotChocolate.Federation
HotChocolate
생태계에서 하위 그래프를 구축하기 위한 Apollo Federation 지원을 제공합니다. 개별 하위 그래프는 서로 독립적으로 실행될 수 있지만 Federated 지시문을 사용하여 다른 하위 그래프와의 관계를 지정할 수도 있습니다. 자세한 내용은 Apollo Federation 문서를 참조하세요.
ApolloGraphQL.HotChocolate.Federation
패키지가 Nuget에 게시되었습니다. 다음 패키지 참조로 .csproj
파일을 업데이트하세요.
< ItemGroup > < PackageReference Include = " HotChocolate.AspNetCore " Version = " 13.6.0 " /> < PackageReference Include = " ApolloGraphQL.HotChocolate.Federation " Version = " $LatestVersion " /> ItemGroup >
필요한 패키지를 설치한 후 GraphQL 서비스에 Apollo Federation을 등록해야 합니다.
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( )
// register your types and services
;
var app = builder . Build ( ) ;
app . MapGraphQL ( ) ;
app . Run ( ) ;
Federation v1 스키마를 선택하려면 대신
.AddApolloFederation()
확장을 사용해야 합니다.
GraphQL 스키마를 생성하고 서버를 구성하는 방법에 대한 자세한 내용은 HotChocolate
설명서를 참조하세요.
Apollo Federation에서는 하위 그래프가 슈퍼 그래프를 인식할 수 있도록 몇 가지 추가 메타데이터를 제공해야 합니다. 엔터티는 지정된 @key
에 의해 슈퍼그래프 전체에서 고유하게 식별될 수 있는 GraphQL 객체입니다. 엔터티는 다양한 하위 그래프로 확장될 수 있으므로 엔터티에 액세스하려면 추가 진입점이 필요합니다. 즉, 하위 그래프는 지원하는 엔터티에 대한 참조 확인자를 구현해야 합니다.
추가 페더레이션 세부정보는 Apollo 문서를 참조하세요.
모든 연합 지시어는 클래스/필드/메서드에 직접 적용할 수 있는 속성으로 제공됩니다.
[ 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
설명서를 참조하세요.Federation v2 지시문(v1 지시문 모두 포함)
ApolloTag
, @tag
문서 참조ApolloAuthenticated
(v2.5부터) , @authenticated
문서ComposeDirective
(v2.1부터) , @composeDirective
문서 참조Contact
, @contact
사용법 참조Inaccessible
합니다. @inaccessible
문서를 참조하세요.InterfaceObject
(v2.3부터) , @interfaceObject
문서 참조KeyInterface
, 엔터티 인터페이스 @key
문서 참조Link
, @link
설명서 참조RequiresScopes
(v2.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
설명서를 참조하세요.Federation v2 지시문(v1 지시문 모두 포함)
ApolloTag
, @tag
문서 참조ApolloAuthenticated
(v2.5부터) , @authenticated
문서ComposeDirective(name)
(v2.1부터) 스키마에 적용 가능합니다. @composeDirective
문서를 참조하세요.Contact(name, url?, description?)
, @contact
사용법 참조Inaccessible
합니다. @inaccessible
문서를 참조하세요.InterfaceObject
(v2.3부터) , @interfaceObject
문서 참조Key(fieldset)
, @key
문서 참조Link(url, [import]?)
, @link
문서 참조NonResolvableKey(fieldset)
객체에 적용 가능합니다. 확인할 수 없는 @key
문서를 참조하세요.RequiresScopes(scopes)
(v2.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
;
일부 지시문을 적용하여 스키마를 사용자 정의하려는 경우 SchemaTypeDescriptorAttribute
확장하는 속성으로 주석을 추가할 수 있는 사용자 정의 FederatedSchema
제공할 수도 있습니다.
[ 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
Apollo Federation v2 @link
정의를 자동으로 적용하는 공통 FederatedSchema
클래스를 제공합니다. 사용자 정의 스키마 지시문을 적용할 때 이 클래스를 확장하고 필수 특성/지시문을 추가해야 합니다.
@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 Federation 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
지시문을 적용하여 인터페이스를 유형으로 만들어 다른 하위 그래프에서 인터페이스를 확장할 수 있습니다. 이를 통해 인터페이스를 구현하는 모든 엔터티에 새 필드를 추가할 수 있습니다(예: 모든 Product
구현에 Reviews
필드 추가).
[ 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
지시문을 사용하여 팀의 연락처 정보를 하위 그래프 스키마에 추가할 수 있습니다. 이 정보는 Studio에 표시되어 다른 팀이 하위 그래프에 대한 지원을 위해 누구에게 연락해야 하는지 알 수 있도록 도와줍니다. 자세한 내용은 설명서를 참조하세요.
스키마에 [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;
마이그레이션 프로세스를 최대한 원활하게 진행하려고 노력하는 동안 라이브러리를 약간 조정해야 했습니다. 일부 내부 API에 대한 종속성으로 인해 라이브러리에 다음과 같은 주요 변경 사항을 적용해야 했습니다.
[Key]
는 이제 클래스에만 적용 가능하며 더 이상 개별 필드에 적용할 수 없습니다.[ReferenceResolver]
는 이제 엔터티 내의 공개 정적 메서드에만 적용 가능하며 더 이상 클래스에는 적용되지 않습니다. [EntityResolver]
는 엔터티 표현을 지원되는 @key
/ @requires
값에 자동으로 매핑할 수 있습니다. 스칼라 @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(MIT) 라이선스에 따라 라이선스가 부여됩니다.