HotChocolate.ApolloFederation แพ็คเกจ ApolloFederation ตอนนี้รองรับ Federation v2 อย่างสมบูรณ์แล้ว เพื่อให้การบูรณาการในระบบนิเวศ HC ง่ายขึ้น เราได้ตัดสินใจเลิกใช้แพ็คเกจนี้เพื่อสนับสนุนแพ็คเกจในตัวที่มีคุณลักษณะครบถ้วนเพียงชุดเดียวคำเตือน เนื่องจากการเปลี่ยนแปลงครั้งใหญ่ของ API สาธารณะ เราไม่สามารถรองรับ
HotChocolateเวอร์ชันใหม่กว่าได้จนกว่า API ทดแทน (ขณะนี้อยู่ระหว่างดำเนินการ) จะเสร็จสมบูรณ์ เรารองรับได้เฉพาะรุ่น v13.5.xและ v13.6.xเท่านั้น
Apollo Federation เป็นสถาปัตยกรรมแบบเปิดที่ทรงพลังซึ่งช่วยให้คุณสร้าง supergraph แบบรวม ที่รวม GraphQL API หลายตัวเข้าด้วยกัน ApolloGraphQL.HotChocolate.Federation ให้การสนับสนุน Apollo Federation สำหรับการสร้างกราฟย่อยในระบบนิเวศ HotChocolate กราฟย่อยแต่ละรายการสามารถรันได้อย่างอิสระจากกัน แต่ยังสามารถระบุความสัมพันธ์กับกราฟย่อยอื่นๆ ได้โดยใช้คำสั่งแบบรวมศูนย์ ดูเอกสารประกอบของ Apollo Federation สำหรับรายละเอียด
แพ็คเกจ ApolloGraphQL.HotChocolate.Federation ได้รับการเผยแพร่ไปยัง Nuget อัปเดตไฟล์ .csproj ของคุณด้วยการอ้างอิงแพ็คเกจต่อไปนี้
< 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 >หลังจากติดตั้งแพ็คเกจที่จำเป็นแล้ว คุณจะต้องลงทะเบียน Apollo Federation กับบริการ GraphQL ของคุณ
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()แทน
โปรดดูเอกสารประกอบ HotChocolate สำหรับข้อมูลโดยละเอียดเกี่ยวกับวิธีสร้างสคีมา GraphQL และกำหนดค่าเซิร์ฟเวอร์ของคุณ
Apollo Federation กำหนดให้กราฟย่อยจัดเตรียมข้อมูลเมตาเพิ่มเติมเพื่อให้ Supergraph ทราบ เอนทิตีคืออ็อบเจ็กต์ GraphQL ที่สามารถระบุได้โดยไม่ซ้ำกันใน supergraph โดย @key s ที่ระบุ เนื่องจากเอนทิตีสามารถขยายได้ด้วยกราฟย่อยต่างๆ เราจึงต้องมีจุดเริ่มต้นเพิ่มเติมเพื่อเข้าถึงเอนทิตี กล่าวคือ กราฟย่อยจำเป็นต้องใช้ตัวแก้ไขการอ้างอิงสำหรับเอนทิตีที่พวกเขาสนับสนุน
ดูเอกสาร 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 ใช้ได้กับวัตถุ ดูเอกสารประกอบ @extendsExternal ใช้ได้กับฟิลด์ โปรดดูเอกสาร @externalKey ที่ใช้ได้กับออบเจ็กต์ ดูเอกสารประกอบ @keyProvides ข้อมูลที่เกี่ยวข้องในฟิลด์ ดูที่ @provides เอกสารประกอบRequires มีผลบังคับใช้ในฟิลด์ โปรดดู @requires เอกสารประกอบคำสั่ง Federation v2 (รวมคำสั่ง v1 ทั้งหมด)
ApolloTag ใช้ได้กับสคีมา โปรดดูเอกสารประกอบ @tagApolloAuthenticated (ตั้งแต่ v2.5) ใช้ได้กับ enum, ฟิลด์, อินเทอร์เฟซและอ็อบเจ็กต์, เอกสาร @authenticatedComposeDirective (ตั้งแต่เวอร์ชัน 2.1) ใช้ได้กับสคีมา โปรดดูเอกสาร @composeDirectiveContact ที่ใช้งานได้บนสคีมา ดูที่การใช้งาน @contactInaccessible เข้าถึงได้ ใช้ได้กับคำจำกัดความทุกประเภท ดูเอกสารประกอบ @inaccessibleInterfaceObject (ตั้งแต่ v2.3) ใช้ได้กับอ็อบเจ็กต์ โปรดดูเอกสารประกอบ @interfaceObjectKeyInterface ใช้ได้กับอินเทอร์เฟซ โปรดดูเอกสารประกอบ @key ของอินเทอร์เฟซเอนทิตีLink ใช้ได้กับสคีมา ดูเอกสารประกอบ @linkRequiresScopes (ตั้งแต่ v2.5) ใช้ได้กับ enum, ฟิลด์, อินเทอร์เฟซและอ็อบเจ็กต์, เอกสาร @requiresScopesShareable ได้บนสคีมา ดูเอกสารประกอบ @shareableความละเอียดของเอนทิตี
Map ที่ใช้ได้กับพารามิเตอร์วิธีการแก้ไขเอนทิตี ช่วยให้คุณสามารถแมปอาร์กิวเมนต์ที่ซับซ้อนกับค่าการแสดงที่ง่ายกว่า เช่น [Map("foo.bar")] string barReferenceResolver ใช้ได้กับ วิธีสาธารณะแบบคง ที่ภายในคลาสเอนทิตีเพื่อระบุตัวแก้ไขเอนทิตีอีกทางหนึ่ง หากคุณต้องการการควบคุมที่ละเอียดยิ่งขึ้น คุณสามารถใช้โค้ดวิธีแรกและเติมข้อมูลการรวมด้วยตนเองบนตัวอธิบายประเภท 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 ใช้ได้กับออบเจ็กต์ ดูเอกสารประกอบ @extendsExternal ใช้ได้กับฟิลด์ โปรดดูเอกสาร @externalKey(fieldset) ใช้ได้กับอ็อบเจ็กต์ ดูเอกสารประกอบ @keyProvides(fieldset) ใช้ได้กับฟิลด์ ดู @provides เอกสารประกอบRequires(fieldset) ใช้ได้กับฟิลด์ ดู @requires เอกสารประกอบคำสั่ง Federation v2 (รวมคำสั่ง v1 ทั้งหมด)
ApolloTag ใช้ได้กับคำจำกัดความทุกประเภท โปรดดูเอกสารประกอบ @tagApolloAuthenticated (ตั้งแต่ v2.5) ใช้ได้กับ enum, ฟิลด์, อินเทอร์เฟซและอ็อบเจ็กต์, เอกสาร @authenticatedComposeDirective(name) (ตั้งแต่ v2.1) ใช้ได้กับสคีมา โปรดดูเอกสาร @composeDirectiveContact(name, url?, description?) ใช้ได้กับสคีมา โปรดดูที่การใช้งาน @contactInaccessible เข้าถึงได้ ใช้ได้กับคำจำกัดความทุกประเภท ดูเอกสารประกอบ @inaccessibleInterfaceObject (ตั้งแต่ v2.3) ใช้ได้กับอ็อบเจ็กต์ โปรดดูเอกสารประกอบ @interfaceObjectKey(fieldset) ใช้ได้กับอ็อบเจ็กต์ ดูเอกสารประกอบ @keyLink(url, [import]?) ใช้ได้กับสคีมา ดูเอกสาร @linkNonResolvableKey(fieldset) ใช้ได้กับออบเจ็กต์ ดูเอกสารประกอบ @key ที่ไม่สามารถแก้ไขได้RequiresScopes(scopes) (ตั้งแต่ v2.5) ใช้ได้กับ enum, field, interface และ object, เอกสาร @requiresScopesShareable ได้กับฟิลด์และออบเจ็กต์ ดูเอกสารประกอบ @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 จะสร้างสคีมาโดยใช้เวอร์ชัน Federation ที่รองรับล่าสุด หากคุณต้องการเลือกใช้เวอร์ชันเก่า คุณสามารถทำได้โดยการระบุเวอร์ชันเมื่อกำหนดค่าส่วนขยาย AddApolloFederationV2
builder . Services
. AddGraphQLServer ( )
. AddApolloFederationV2 ( FederationVersion . FEDERATION_23 )
// register your types and services
; หรือคุณสามารถจัดเตรียม FederatedSchema แบบกำหนดเองที่กำหนดเป้าหมายเวอร์ชันของ Federation ที่เฉพาะเจาะจงได้
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 ที่ไม่สามารถแก้ไขได้ กราฟย่อยของคุณสามารถใช้เอนทิตีเป็นประเภทการส่งคืนของฟิลด์โดยไม่ต้องมีส่วนในฟิลด์ใดๆ ให้กับเอนทิตีนั้น เนื่องจากเรายังต้องการคำจำกัดความประเภทเพื่อสร้างสคีมาที่ถูกต้อง เราจึงสามารถกำหนดอ็อบเจ็กต์ stub ด้วย [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 ทั่วไปที่ใช้ข้อกำหนด @link ของ Apollo Federation v2 โดยอัตโนมัติ เมื่อใช้คำสั่งสคีมาที่กำหนดเอง คุณควรขยายคลาสนี้และเพิ่มแอตทริบิวต์/คำสั่งที่จำเป็น
เมื่อใช้ @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
; @interfaceObjectApollo Federation v2 รองรับ อินเทอร์เฟซเอนทิตี ซึ่งเป็นส่วนขยายที่มีประสิทธิภาพสำหรับอินเทอร์เฟซ GraphQL ที่ช่วยให้คุณสามารถขยายฟังก์ชันการทำงานของอินเทอร์เฟซทั่วทั้ง supergraph โดยไม่ต้องปรับใช้ (หรือแม้แต่ระวัง) ประเภทการใช้งานทั้งหมด
ในกราฟย่อยที่กำหนดอินเทอร์เฟซเราจำเป็นต้องใช้ @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 ใช้เพื่อระบุว่าองค์ประกอบเป้าหมายสามารถเข้าถึงได้เฉพาะกับผู้ใช้ supergraph ที่ได้รับการรับรองความถูกต้องด้วยขอบเขต 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 เป็นเรื่องง่าย เพียงอัปเดตการนำเข้าแพ็คเกจของคุณให้ชี้ไปที่โมดูลใหม่
<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>และอัปเดตการนำเข้าเนมสเปซ
- using HotChocolate.ApolloFederation;
+ using ApolloGraphQL.HotChocolate.Federation;แม้ว่าเราพยายามทำให้กระบวนการย้ายข้อมูลราบรื่นที่สุดเท่าที่จะเป็นไปได้ แต่เราก็ต้องปรับแต่งไลบรารีเล็กน้อย เนื่องจากการพึ่งพา API ภายในบางตัว เราจึงต้องทำการเปลี่ยนแปลงที่สำคัญในไลบรารีดังต่อไปนี้:
[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 ของเรา
ในการเริ่มต้น โปรดแยก repo และชำระเงินสาขาใหม่ จากนั้นคุณสามารถสร้างไลบรารีภายในเครื่องได้โดยการรัน
# install dependencies
dotnet restore
# build project
dotnet build
# run tests
dotnet testดูข้อมูลเพิ่มเติมใน CONTRIBUTING.md
หลังจากที่คุณได้จัดตั้งสาขาในพื้นที่แล้ว โปรดดูปัญหาที่เปิดอยู่ของเราเพื่อดูว่าคุณสามารถมีส่วนร่วมได้ที่ไหน
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการติดต่อทีมงานเกี่ยวกับปัญหาด้านความปลอดภัย โปรดดูนโยบายความปลอดภัยของเรา