-
Notifications
You must be signed in to change notification settings - Fork 14
Add JsonSchema support to fastify plugin. #60
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
Conversation
https://fastify.dev/docs/latest/Reference/Validation-and-Serialization/#serialization I opted to only handle response schemas since (from my understanding) that is where most of the performance gain is at using `fast-json-stringify`. The request schemas are mostly for validation, which Facility can already take care of for us.
|
||
if (response.BodyField is not null) | ||
{ | ||
code.WriteLine($"{GetJsonSchemaType(response.BodyField.ServiceField.TypeName)},"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code.WriteLine($"{GetJsonSchemaType(response.BodyField.ServiceField.TypeName)},"); | |
code.WriteLine($"{GetJsonSchemaType(service.GetFieldType(response.BodyField.ServiceField))},"); |
This would be a more typical implementation, which would allow GetJsonSchemaType
to switch on fieldType.Kind
instead of reverse-engineering the type name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You beat me to it! I was going to ask if there was a better way, which I assumed there was. π
@@ -543,6 +543,7 @@ private CodeGenOutput GenerateFastifyPluginOutput(ServiceInfo service) | |||
var capModuleName = CodeGenUtility.Capitalize(moduleName); | |||
var camelCaseModuleName = CodeGenUtility.ToCamelCase(moduleName); | |||
var pluginFileName = CodeGenUtility.Uncapitalize(moduleName) + "Plugin" + (TypeScript ? ".ts" : ".js"); | |||
var customTypes = new HashSet<string>(service.Dtos.Select(x => x.Name).Concat(service.Enums.Select(x => x.Name))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think when I add .NET 8 support, I'll drop .NET Standard 2.0 from the code gen libraries so they can use modern constructs like ToHashSet()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good!
instead of digging into the type name directly.
if (serviceType is null) | ||
throw new ArgumentNullException(nameof(serviceType)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServiceInfo.GetServiceType
can return null
, so I opted to handle that explicitly here instead of using !
at the call sites. @ejball What is the scenario where this will be null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would only be null if the type name was invalid, which shouldn't be possible if the service parsed successfully. Probably it should have thrown an exception on an invalid type and introduced a separate Try
method for possibly returning null.
In any case, it doesn't seem correct to communicate that null is okay in the signature and then throw if it is passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change to use !
at the call sites then. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed: 51f5c1f
|
||
return serviceType.Kind switch | ||
{ | ||
ServiceTypeKind.String or ServiceTypeKind.Bytes or ServiceTypeKind.DateTime or ServiceTypeKind.ExternalEnum => $"{{ type: '{"string"}' }}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServiceTypeKind.String or ServiceTypeKind.Bytes or ServiceTypeKind.DateTime or ServiceTypeKind.ExternalEnum => $"{{ type: '{"string"}' }}", | |
ServiceTypeKind.String or ServiceTypeKind.Bytes or ServiceTypeKind.DateTime or ServiceTypeKind.ExternalEnum => "{ type: 'string' }", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I did have this originally, but was getting a Probable JSON string detected (JSON002)
linting error, which seemed strange. I'm not actually sure where it is coming from, I can't find anything online about it. I can disable it inline for this method, or maybe make it a suggestion instead of a an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's what I've found on that now: https://www.infoq.com/news/2022/11/visual-studio-tagged-strings/
Basically, I can add /*lang=json*/
to each line to let Roslyn check it for syntax errors. TIL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the comments (in this particular case) hurt readability though, so I vote for adding dotnet_diagnostic.JSON002.severity = suggestion
to .editorconfig
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix: 580c68b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL
ServiceTypeKind.Error => $"{{ $ref: '{"_error"}' }}", | ||
ServiceTypeKind.Dto => $"{{ $ref: '{serviceType.Dto!.Name}' }}", | ||
ServiceTypeKind.Enum => $"{{ $ref: '{serviceType.Enum!.Name}' }}", | ||
ServiceTypeKind.Result => $"{{ type: 'object', properties: {{ value: {GetJsonSchemaType(serviceType.ValueType!)}, error: {{ $ref: '_error' }} }} }}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServiceTypeKind.Result => $"{{ type: 'object', properties: {{ value: {GetJsonSchemaType(serviceType.ValueType!)}, error: {{ $ref: '_error' }} }} }}", | |
ServiceTypeKind.Result => $$"""{ type: 'object', properties: { value: {{GetJsonSchemaType(serviceType.ValueType!)}}, error: { $ref: '_error' } } }", |
I can't tell if this is better or not...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've got to double on braces somewhere I suppose. The current version is what I'm more familiar with as I don't see the """
syntax as much.
Instead we just set it to a suggestion in `.editorconfig`
@ejball ππΌ ππΌ ? |
https://fastify.dev/docs/latest/Reference/Validation-and-Serialization/#serialization
I opted to only handle response schemas since (from my understanding) that is where most of the performance gain is at using
fast-json-stringify
. The request schemas are mostly for validation, which Facility can already take care of for us.