graphql-compose-mongoose icon indicating copy to clipboard operation
graphql-compose-mongoose copied to clipboard

how to reconcile mongoose number type with graphql float and int types

Open keeganstothert opened this issue 5 years ago • 3 comments

By default this library assumes that the number type in the mongoose schema is a float. How can I explicitly make it an Int?

keeganstothert avatar Dec 09 '20 23:12 keeganstothert

i found one way

ExposureTC.extendField("duration", { type: GraphQLInt });

keeganstothert avatar Dec 09 '20 23:12 keeganstothert

Interesting... we ran into the same issue with Decimal, specifically we want the serialize method to call the value with Number instead of String. We had to create our own custom GraphQLScalarType, and then use extendField like @keeganstothert did.

Is there any way we can make the behavior of graphql-compose-mongoose customizable from the jump? Maybe make it possible to provide some Type to override the default behavior for a given mongoose Type?

const MyObjectTC = composeMongoose(MySchema, { typeMap: { Decimal: MyCustomBSONDecimal } })

I see this most useful for Decimal, since the majority of the use cases I have come across end up using some get / set combo in the schema definition - creating custom behavior that is not accounted for when composing to graphql.

I would be willing to make a PR, just would prefer to get author's thoughts first.

jsrhodes15 avatar Apr 12 '21 21:04 jsrhodes15

@jsrhodes15 sorry for the late response.

For replacing built-in Decimal type you may provide your own type before composeMongoose calling:

schemaComposer.set('BSONDecimal', YourCustomDecimalType);

I don't feel that typeMap solution will be widely used. For Decimal I recommend the solution above, but for { Number: Int/Float } it can be unusable – what if you want to make several fields as Int and others as Float.

Maybe better provide an option that allows overriding types per-field basis or even more extending them. Eg:

// as shortand for type replacement
const MyObjectTC = composeMongoose(MySchema, { extendFields: { 
  price: MyCustomBSONDecimal,
  qty: 'Int',
} }); 

// field config overriding & adding new one computable field
const MyObjectTC = composeMongoose(MySchema, { extendFields: { 
  price: { 
    type: MyCustomBSONDecimal,
    description: 'My special field description',
  },
  qty: 'Int',
  newComputableField: {
    type: MyCustomBSONDecimal,
    resolve: (source) => source.qty * source.price,
  } 
});

@jsrhodes15 what do you think?

nodkz avatar Apr 22 '21 17:04 nodkz