Skip to content

Refactor JSON generation process to support a plugin architecture #597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 10, 2017

Conversation

shlomiassaf
Copy link
Contributor

This PR refactor JSON serialization so it will run through the plugin system and not through a class inheritance model.

A Class inheritance model is limiting and does not allow customisation.

With this PR every type that requires serialization must come with a serializer plugin.

The PR includes serializer plugins for Reflection and all classes derived from it, Type and all derived, group, source reference and any other type that was part of the toObject() process. In some places a plugin was created to object's previously converted ad-hoc (source reference, decorators).
The implementation mimic the old behaviour 1:1

This approach allows full integration with JSON serialization in an easy way.

Reviewers:

The PR is not small so I push it in 4 commits where 2 of the commits are 99% of the changes but 1 of the commits is addition only, the other is repetitive changes to the code.

1959aaaf7c10d872e834a57d8bfa38ec9cb3827a - The implementation of the new feature. New files and new logic, no code change.

ce2fb73b80dda9e65a81eb6cec969729a7358e57 - Miniature change to tsconfig to support types for es2015 core functionallity

9351d2a169c1a5912d336473bf0db43f696829a9 - A big commit with non-code change (comments). Basically it adds @deprecated tags to old toObject() methods.

54a165f9134a8d8e137d99275483e9af920fc4d2 - Small commit that activates the new plugin in application.ts
Read more: #595

@shlomiassaf shlomiassaf mentioned this pull request Sep 24, 2017
9 tasks
@aciccarello
Copy link
Collaborator

Nice work! From the quick look I took seems like a good idea.

@shlomiassaf
Copy link
Contributor Author

@aciccarello @blakeembrey

I'v rebased and added support to the new TypeOperator type (#614)

This is a big feature that will help a lot for customization where people don't want to render a static site but want to relay on data with a SPA site... or using external engines to create the a site...

I understand it's a big feature and merging this big chunk of code might be risky for you, so here's what I suggest we can do to push this:

I've made sure not to remove the toObject() method in each model, I just added a @deprecated comment to these methods.

Since we have that logic we can introduce a new option flag to opt-in to the new serialization system. This way the behaviour is the same unless you opt-in, no harm.

In the next major version, 1.0.0, we will remove the toObject() methods and move to the new system, so we won't need to duplicate the serialization logic whenever we change it or add new types.

I'm not a good "namer", but we can call the flag useSerializationHost

typedoc --json my-json.json --useSerializationHost

@aciccarello
Copy link
Collaborator

@shlomiassaf thanks for the additional tweaks. I'm on vacation this week but hopefully I can do a final review next week. Your work this far has been great. much appreciated.


initialize(): void {
super.initialize();
this.supports = (r: CommentTag) => true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these support methods initialized on each instance instead of on the prototype?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

purely speaking, this can be done in the prototype as a method and not a property, but it's not that important in this context because it's a plugin and only get's a instanciated once throughout the whole app.

I think the reason I did it that way is because it's done like that in other plugins I looked at to learn from.

@shlomiassaf
Copy link
Contributor Author

@aciccarello I see a rebase is required, once you finish the review and ready to merge please comment here so I'll rebase

Shlomi Assaf (shlassaf) added 9 commits November 1, 2017 15:34
…lugin and child plugins, mimics 1:1 output of toObject() logic
It is essential that they are removed, if not the code will contain duplicate logic which is a risk over time.
this is a legacy bug that was taken from the old toObject implementation
@shlomiassaf
Copy link
Contributor Author

@aciccarello I rebased because I added a fix

The fix is actually also a fix in the current implementation...

@aciccarello aciccarello merged commit 34377dc into TypeStrong:master Nov 10, 2017
@aciccarello
Copy link
Collaborator

@shlomiassaf Thanks for the work and for being patient!

@mootari
Copy link

mootari commented Jan 18, 2018

@aciccarello Any chance you could publish a pre-release (tagged release, e.g. using the tag "next") to npm?

@lddubeau
Copy link
Contributor

The serialization mechanism added by this commit seems to be in production as evidenced here.

However, it does not seem to be formally tested anywhere, because the code that generates serializations for testing purposes still uses the old toObject method provided by the Reflection class hierarchy. (See here, here, here, and here.)

Gerrit0 added a commit that referenced this pull request Jun 28, 2020
Partially reverts #597, while still preserving the ability for serialization to be modified by plugins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants