asp.net core graphql with hotchocolate #2

asp.net core graphql with hotchocolate #1에 있었던 DateTime을 Date로 변환하는 문제를 다르게 해결 할 수있는 방법에 대해 이야기 해보려한다.

목차

1. Query만들기

2. ObjectType만들기

3. 굳이 이렇게 까지 해야하는가?

4. 결론


본문

1. Query만들기

using HotChocolate.Types;
using MyPension.Graphql.Types;
using MyPension.Services;

namespace MyPension.Graphql.Services
{
    public class PensionServiceQuery : ObjectType<PensionService>
    {
        protected override void Configure(IObjectTypeDescriptor<PensionService> descriptor)
        {
            base.Configure(descriptor);

            descriptor.Field(f => f.SearchMember(default!))
                      .Type<ListType<MemberType>>();
        }
    }
}

위와 같이 기존 PensionService를 GraphQL 서비스로 만들어야 한다.

2. ObjectType만들기

Version 1 Member의 BirthDay 속성 타입 변경

using HotChocolate.Types;
using MyPension.Dtos.VO;

namespace MyPension.Graphql.Types
{
    public class MemberType : ObjectType<MemberVO>
    {
        protected override void Configure(IObjectTypeDescriptor<MemberVO> descriptor)
        {
            base.Configure(descriptor);
            descriptor.Field(f => f.BirthDay).Type<DateType>();
        }
    }
}

Version 2 Member의 BirthDay 날짜 포맷 String으로 변경

using HotChocolate.Types;
using MyPension.Dtos.VO;

namespace MyPension.Graphql.Types
{
    public class MemberType : ObjectType<MemberVO>
    {
        protected override void Configure(IObjectTypeDescriptor<MemberVO> descriptor)
        {
            base.Configure(descriptor);
            descriptor.Field(f => f.BirthDay.ToString("yyyy-MM-dd"));

        }
    }
}

결과는 같다 #1에서도 설명했지만 graphql은 String, ID(결국 String), Int, Float, Boolean 밖에 없으므로
DateType으로 형변환해도 최종 결과는 String이다.

마지막으로 Startup.cs의 다음 코드를 변경한다.

// services.AddGraphQLServer().AddQueryType<MyPension.Services.PensionService>()
services.AddGraphQLServer().AddQueryType<MyPension.Graphql.Services.PensionServiceQuery>()

3. 굳이 이렇게 까지 해야하는가?

위의 PensionService 클래스는 graphql과 아무런 상관없는 그냥 서비스 클래스이다. 이 클래스는 자신이 rest에 이용될지 graphql에 이용될지 rpc에 이용될지 모른다. 그냥 요청한 서비스만 잘 처리하면 된다.

마찬가지로 #1에 있었던 MemberVO 클래스 역시 자신이 어디에 사용될지 모르지만 DateTime을 Date형으로 변경하기 위해 아래 코드와 같이 GraphQLType attribute를 사용했을 경우는 내가 Graphql에서 사용되는지를 안다.(물론 안쓰면 그만)

[GraphQLType(typeof(HotChocolate.Types.DateType))]
public DateTime BirthDay { get; set; }

하지만 기존에 rest로 잘 사용하고 있는 서비스에 graphql도 제공한다고 가정했을때 MemberVO를 dll로만 제공받았을 때 우리는 Attribute를 선언 할 수 없다. 그렇다고 MemberVO를 상속받은 MemberVO2를 만든 후 GraphQLType attribute를 선언해서 사용하면 될 것 같지만 그럴 수 없다. MemberVO를 반환하는 모든 서비스를 MeMberVO2로 변경해야 한다. 우리가 원하는 거는 단순히 기존 서비스의 반환 값을 Graphql로 제공하려는 것 뿐이다.

4. 결론

실제 프로젝트를 진행하다보면 Assembly를 어느 정도까지 분리해야 하는지 항상 고민 되는 부분이다.
특히 Server도 c#이고 Client도 c#이라면 xxxx.Packets.dll 따위의 Assembly는 공유하고 싶다. 하지만 그렇게 하지마라 Utility성 assembly가 아니라면 각각 갖고 있는게 맘편하다. 그런면에서 schema가 확실한 graphql은 좋은 대안이 될 수 있다.

좋은 웹페이지 즐겨찾기