deepkit-framework icon indicating copy to clipboard operation
deepkit-framework copied to clipboard

Ability to cherry-pick groups next to default fields / Define groups that are by default excluded.

Open Rush opened this issue 4 years ago • 8 comments

import { t, jsonSerializer } from '@deepkit/type';

class Foo {
  @t
  name!: string;

  @t.any.group('withDetails')
  veryBigObject!: any;
}


const out = jsonSerializer.for(Foo).deserialize({
  name: 'foo',
  veryBigObject: { abc: 1, def: 2 } // imagine this is huge
}, { groups: [] });

console.log(out); // don't want `veryBigObject` here as we're compiling without `withDetails`

const outWithDetails = jsonSerializer.for(Foo).deserialize({
  name: 'foo',
  veryBigObject: { abc: 1, def: 2 } // imagine this is huge
}, { groups: [ 'withDetails' ] });

console.log(outWithDetails);

Result is:

Foo { name: 'foo', veryBigObject: { abc: 1, def: 2 } }
Foo { veryBigObject: { abc: 1, def: 2 } }

But expected result would be:

Foo { name: 'foo'  }
Foo { name: 'foo', veryBigObject: { abc: 1, def: 2 } }

So it's kind of opposite to how I imagine groups should work ;) I'd like the user of the API to cherry pick "additional groups" they want to see on top of the default fields.

This would map it to how class-transformer works.

Rush avatar Jan 07 '21 05:01 Rush

You can use jsonSerializer.for(Foo).deserialize(..., { groupsExclude: [ 'withDetails' ] });. If you want to include only properties that have no groups assigned, you can now use {groups: []}.

marcj avatar Jan 07 '21 13:01 marcj

If you want to include only properties that have no groups assigned, you can now use {groups: []}.

Right but what if I want to have both fields with no groups assigned PLUS some groups. groups: [] is kind of an all or nothing thing. I can imagine groupsExclude to become very unwieldy. Imagine having feature flags such as withFeatureX, withFeatureY, withFeatureZ. I think it's much more convenient to say: "Give me this document with all default fields and with feature Z enabled" rather than to say "Give me this document with feature X and Y". The latter is also more bug prone when adding new sets of groups to the classes as it will by default expose them.

Rush avatar Jan 07 '21 18:01 Rush

You could add a group to each field then, e.g. a default. This is probably the most secure and stable way.

marcj avatar Jan 07 '21 18:01 marcj

You could add a group to each field then, e.g. a default. This is probably the most secure and stable way.

Agreed it would work. But this adds verbosity. Judging by the API @t the idea is to have a default behavior that's quick and easy. :)

Why not have an additional groupsInclude which would be the opposite of groupsExclude and it would do exactly what I am describing?

groupsInclude: [] - Should return all fields with no group specified. It should exclude all fields with groups. groupsInclude: ['foo'] - Should return all fields with no group specific. In addition it should include group 'foo'

Rush avatar Jan 07 '21 18:01 Rush

Why not have an additional groupsInclude which would be the opposite of groupsExclude and it would do exactly what I am describing?

Yes, that would make sense 👍

marcj avatar Jan 07 '21 18:01 marcj

Alternatively maybe there could be a symbol for representing a default group. Such as:

// somewhere in the deepkit src
export const NO_GROUP = new Symbol('NO_GROUP');
groups [ NO_GROUP, 'foo' ] 

PS. Probably it would deserve better naming :-P

Rush avatar Jan 07 '21 18:01 Rush

And one more alternative that I came up with:

groups: [, 'foo' ]
» node
Welcome to Node.js v14.15.0.
Type ".help" for more information.
> [, 'foo']
[ <1 empty item>, 'foo' ]

This empty item could be recognized as wanting to include fields with no groups specified.

Rush avatar Jan 07 '21 18:01 Rush

Alternative API

const item = jsonSerializer.for(Foo).withGroups('foo', 'bar').includeNoGroup().serialize(item);


const serializer = jsonSerializer.for(Foo).withGroups('foo', 'bar').includeNoGroup()
const item = serializer.serialize(item);

marcj avatar Jan 13 '21 14:01 marcj