Add JsonSchema support to fastify plugin.#60
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.
| 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.
You beat me to it! I was going to ask if there was a better way, which I assumed there was. 👍
| 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.
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().
instead of digging into the type name directly.
| if (serviceType is null) | ||
| throw new ArgumentNullException(nameof(serviceType)); |
There was a problem hiding this comment.
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.
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.
Will change to use ! at the call sites then. Thanks!
|
|
||
| return serviceType.Kind switch | ||
| { | ||
| ServiceTypeKind.String or ServiceTypeKind.Bytes or ServiceTypeKind.DateTime or ServiceTypeKind.ExternalEnum => $"{{ type: '{"string"}' }}", |
There was a problem hiding this comment.
| 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.
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.
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.
I think the comments (in this particular case) hurt readability though, so I vote for adding dotnet_diagnostic.JSON002.severity = suggestion to .editorconfig.
| 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.
| 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.
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.