ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.25k stars 744 forks source link

Support for TimeSpan Scalar in Mutation #2200

Closed bbehling closed 4 years ago

bbehling commented 4 years ago

TimeSpan support is not available in HotChocolate mutations.

In queries, TimeSpan seems to work because no errors are thrown when adding the ScheduleQuery type, and also returns a TimeSpan class with values in the result.

 services
                 .AddDataLoaderRegistry()
                 .AddGraphQL(SchemaBuilder
                    .New()
                    .AddQueryType(d => d.Name("Query"))
                    .AddType<ScheduleQuery>()
                    .AddMutationType(m => m.Name("Mutation"))
                    .AddType<ScheduleMutation>()
                    .Create());

error: HotChocolate.SchemaException: 'Unable to infer or resolve a schema type from the type reference `Input: System.TimeSpan`.'

  [ExtendObjectType(Name = "Mutation")]
    public class ScheduleMutation
    {
        public async Task<Schedule> Schedule([Service] HISContext context, string Name, IEnumerable<Interval> intervals) {

            var schedule = new Schedule
            {
                Name = Name,
                Intervals = intervals
            };

            context.Schedules.Add(schedule);
            await context.SaveChangesAsync();
            return schedule;

        }
    }
public class Schedule 
    {
        public string Name { get;  set; }
        [GraphQLType(typeof(AnyType))]
        public IEnumerable<Interval> Intervals { get;  set; }

        public Schedule() { }

        internal static Schedule Create(string name, IEnumerable<Interval> intervals)
        {
            if (string.IsNullOrEmpty(name))
                throw new HISDomainException("Failed to Create Schedue: Name cannot be null or empty");

            return new Schedule()
            {
                Name = name,
                Intervals = intervals
            };
        }
    }

    public class Interval
    {
        public enum Day
        {
            Monday,
            Tuesday,
            Wednesday,
            Thursday,
            Friday,
            Saturday,
            Sunday
        }
        [GraphQLType(typeof(AnyType))]
        public TimeSpan StartTime { get; set; }
       // [GraphQLType(typeof(AnyType))]
        public TimeSpan EndTime { get; set; }

        public IEnumerable<Day> Days { get; set; }

        public static Interval Create(TimeSpan startTime, TimeSpan endTime, IEnumerable<Day> days)
        {
            if(endTime.TotalMilliseconds > startTime.TotalMilliseconds)
                throw new HISDomainException("Failed to Create Schedue: Start Time cannot occur after End Time");

            return new Interval()
            {
                StartTime = startTime,
                EndTime = endTime,
                Days = days
            };
        }

    }

Major design issue with that is now we need Hot Chocolate decorators in the Models.

Describe the solution you'd like Support for TimeSpan Scalars in mutations.

Describe alternatives you've considered Workaround is to add [GraphQLType(typeof(AnyType))] to the TimeSpan properties.

bbehling commented 4 years ago

Closing because this looks to be included with the 11.0 release

https://github.com/ChilliCream/hotchocolate/blob/develop/src/HotChocolate/Core/src/Types/Types/Scalars/TimeSpanType.cs

sar commented 3 years ago

Closing because this looks to be included with the 11.0 release

https://github.com/ChilliCream/hotchocolate/blob/develop/src/HotChocolate/Core/src/Types/Types/Scalars/TimeSpanType.cs

What's the usage example if Mutation is declared with TimeSpan input type?

public class MutationInput {
    [GraphQLType(typeof(TimeSpanType)]
    public TimeSpan Duration {get;set;}
}
mutation {
    addDuration(input: {
         duration: "00h15m00s"        # Javascript Duration String
    }) {
        duration
    }
}

Type of string literal 00h30m00s or int of 900 are not recognized as TimeSpan for automatic deserialization.

https://github.com/ChilliCream/hotchocolate/blob/dc1e317499218419e3a0118ce092006253755394/src/HotChocolate/Core/src/Types/Types/Scalars/TimeSpanType.cs#L42

"errors": [
    {
      "message": "TimeSpan cannot parse the given literal of type `StringValueNode`."
    }
  ],
PascalSenn commented 3 years ago

@sar it nust be in the Iso8601 format. tt:mm:ss.sss