Giter Club home page Giter Club logo

Comments (15)

mobsense avatar mobsense commented on July 21, 2024 2

I understand. We'll do our best. I'll try to set aside some time to prototype and see what we can do here. 100% agreed on the direction as far as TS will allow us to do.

from dynamodb-onetable.

liammullan avatar liammullan commented on July 21, 2024 1

When you say "prototyping" do you mean have a first crack at implementing it? If so I'm not sure I have the expertise yet (I finally bought the dynamodb book today, ha!) Probably more of a medium term goal to make material contribs to this project. I'll start having a poke around the code though...

from dynamodb-onetable.

matthelliwell2 avatar matthelliwell2 commented on July 21, 2024 1

The extra complexity is definitely worth it for me. Types that aren't correct are in some ways worse than no types because people reply on the compiler errors when they see type defintions.

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024 1

I wanted to give an update on this issue. We've been digging into it and are hitting a wall regarding enforcing required properties on create.

Consider the type and the "?".

export type Entity<T extends OneTypedModel> = {
    [P in keyof T]?: EntityField<T[P]>
};

On create, it isn't as simple as just enforcing required properties. There are default properties and computed properties via value templates. When calling create, you can provide a default property or not -- user choice. Similarly, you can provide an explicit value to override a value template computed property. Both of these are necessary in some use-cases. So I don't think we can make a EntityForCreate type that removes the "?" because it would need to also consider default and value templates.

Also note that the update API must supply the keys and one or more fields to update. Find must supply the primary key and optionally the sort key with other fields used to create a filter expression. Get must provide the keys to retrieve the item. I don't want to go down a path of having different type specifiers for each of these APIs.

So we're not coming up with a better solution than the one we have, where TypeScript validates the presence of invalid properties and OneTable validates the required properties. Each has its strength and combined they give pretty good protection.

If you need one step more, then you can always create your own entity type and use that.

Sorry, but I can't see an elegant solution yet.

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024 1

I'm closing this issue for now, but will happily re-open when anyone comes up with an elegant solution.

from dynamodb-onetable.

liammullan avatar liammullan commented on July 21, 2024 1

Many thanks for the thought put into this guys. I'm currently experimenting with dynamodb <-> typescript mapping and if I come to any useful conclusions around this question I'll feed back here.

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024

Maybe.

Currently the library ensures that required properties are defined when calling create. OneTable enforces that.

When updating, you may only want to update one field, so we don't (and can't) require all properties to be present in an update call.

Currently, we use the same type signature for the create/update properties and the returned result. Because you can request via params.fields to retrieve only a subset of the fields via a ProjectionExpression, the returned results from a find, get, update may also only be a subset of the properties.

So the return values may always be a subset of the full model property set.

On the input side, update may receive only a subset too. So that leaves create as the only viable place to ensure that required properties are present and the library currently does check this at runtime.

So it may be possible to have different type signatures for the create API that require all properties that are not required and not default. TypeScript signatures are like limited magic. The control mechanisms are wonderful, but limited.

from dynamodb-onetable.

liammullan avatar liammullan commented on July 21, 2024

Many thanks for the explanation.

Just thinking aloud here, but what about something like... a method on the Model that takes the "partial" flavour of the type, validates it (perhaps using the same code as for create), and returns the "strictly typed" version of it. The strict type could be anonymous.

Something like this would make mapping between OneTable persistent types and app domain types more viable.

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024

Thanks. I'm not a TS expert. What is an "anonymous" type?

Also, would this work if

let user = await User.get({....}, {fields: ['id', 'email']})

So the user will only fetch and contain "id" and "email".

from dynamodb-onetable.

liammullan avatar liammullan commented on July 21, 2024

I'm not either :-) I'm learning. Probably wrong terminology - I meant that we wouldn't need to create a type alias - i.e. a named type - for the "strict" type, necessarily. For your above example you could continue to return the "partial" type.

Another idea though - maybe we could do this the other way around. As part of the schema setup you specify the domain types like so:

type User = {id: string, email: string, displayName? : string}

Then, where partial types are required - e.g. for update input, output of projections (like your example), you explicitly use Partial<User>. A "full" get (without a projection) returns User.

The schema definition type could be modified to work in conjunction with the types - e.g. you can use keyof to ensure that we're referencing valid fields from the appropriate domain type?

I may be getting a bit ahead of myself here - if so I apologise!

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024

Good ideas. I'm not sure how you switch on required == true or not.

Do you want to try prototyping this?

from dynamodb-onetable.

matthelliwell2 avatar matthelliwell2 commented on July 21, 2024

This would be useful but may be more complicated than it looks because how would this type interact with fields that have a hidden or default property set?

Should I be able to pass a field with a default into the create method? If so then the field should be optional when calling create even though it is a required field in the model. Perhaps you can get around this by enforcing that required is always false if a default is set.

Similarly I'm not sure how the type would behave with a hidden field but it might need some thought.

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024

Yes, you can pass a field into create that has a default. It is optional and overrides the default value.

The end result would be 2 types per model. One for updates and one for create. The create params would enforce required params and the update params would have all properties be optional. My question is: is the extra complexity of this worth it?

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024

See also related issue #79

from dynamodb-onetable.

mobsense avatar mobsense commented on July 21, 2024

Thank you. If you do have some insights / improvements. Please break them up so we can more easily digest and apply quickly. A monolithic / fork-lift patch is hard to assimilate.

from dynamodb-onetable.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.