Allow customized generating of additionalProperties in openapi 3 emitter
Clear and concise description of the problem
Motivation
I use typespec (compiler version 0.54.0) to describe my API and generate openapi3 specification (@typespec/openapi3 emitter of version 0.54.0). This specification is shared across different commands to generate client for my service. One of the clients is written in c# and uses NSwag generator.
The problem is that generated openapi spec does not contain explicitly defined attribute additionalProperties: false. It leads to generating IDictionary<string, object> AdditionalProperties for each generated type. Related issue in nswag.
Seems like that the reason is json schema validation specification
Example
Model in typespec:
model Country {
id: CountryId;
alpha2Code: CountryAlpha2Code;
name: Name;
}
Generated OpenApi:
Dicts.Country:
type: object
required:
- id
- alpha2Code
- name
properties:
id:
$ref: '#/components/schemas/Dicts.CountryId'
alpha2Code:
$ref: '#/components/schemas/Dicts.CountryAlpha2Code'
name:
$ref: '#/components/schemas/Dicts.Name'
Generated c# code:
public partial class Country
{
[Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
public string Id { get; set; }
[Newtonsoft.Json.JsonProperty("alpha2Code", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[System.ComponentModel.DataAnnotations.RegularExpression(@"^[A-Z]{3}$")]
public string Alpha2Code { get; set; }
[Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public Name Name { get; set; } = new Name();
private System.Collections.Generic.IDictionary<string, object> _additionalProperties;
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>()); }
set { _additionalProperties = value; }
}
}
Proposal
It will be very useful to have opportunity to specify emitter option - specify explicitly additional properties or not. Like that:
options:
"@typespec/openapi3":
explicitAdditionalPropertiesFalse: true
or:
options:
"@typespec/openapi3":
useDefaultAdditionalPropertiesValue: "false"
It should produce the following openapi:
Dicts.Country:
type: object
required:
- id
- alpha2Code
- name
additionapProperties: false
properties:
id:
$ref: '#/components/schemas/Dicts.CountryId'
alpha2Code:
$ref: '#/components/schemas/Dicts.CountryAlpha2Code'
name:
$ref: '#/components/schemas/Dicts.Name'
Checklist
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
See https://github.com/microsoft/typespec/issues/3549#issuecomment-2166501680. Setting additionalProperties: false across all models would basically muddy intended semantics of extends syntax. It would have to be a decorator, and it would probably need a fair amount of build time error handling to prevent confusing situations.
However unevaluatedProperties probably makes sense as a schema-gen-wide config option.
Coming from swashbuckle I noticed somethings started getting omitted from being generated and it was due to missing additional type refs.