I am building an API and using swagger to test the endpoints. I have a ProductDTO:
public string ProductName { get; set; }
.
.
.
public Price Price { get; set; }
in this DTO I want to use Price class which is used throughout my code. Price class looks like this:
public class Price
{
public Price(decimal amount, string currency)
{
Amount = amount;
Currency = currency;
}
public decimal Amount { get; private set; }
public string Currency { get; private set; }
}
But since private setters are used in Price
class I cannot set these values using swagger (it has readonly
attribute on those). I really like this approach of having private setters and setting values with constructor, which by the way is public. Is there any way I could set values for Price
class using swagger and still use private setters on properties?
Used within an object schema, additionalProperties allows objects conforming to the schema to include properties that are not explicitly named in the properties section of the schema. However, Swagger's core libraries deviate from the specification in subtle ways that can cause unexpected behavior.
To make the class properties visible in Swagger, we have to annotate them with @ApiProperty (). As discussed, we annotate the properties in our class with the @ApiProperty () decorator. See below: If we check the swagger definition now, we will see the below format:
Swagger UI accepts configuration parameters in four locations. From lowest to highest precedence: The swagger-config.yaml in the project root directory, if it exists, is baked into the application configuration object passed as an argument to Swagger UI (SwaggerUI ({...
The full-featured schema representation makes use of the Model class and its subclasses in the swagger-models module of the swagger-core project. ComposedModel is used for allOf schemas and has no provision for directly contained properties
Update: My original answer (see further below) was that this is not possible, however, this really depends on the serialization library used in your project.
For example Newtonsoft's Json.NET allows you to set some of your class' properties via constructor (note: in case your class comes with more than one constructor, apply the JsonConstructorAttribute):
public class Price
{
[JsonConstructor]
public Price(decimal amount, string currency)
{
Amount = amount;
Currency = currency;
}
public decimal Amount { get; private set; }
public string Currency { get; private set; }
}
Original answer
No, this is not possible. Because if you keep your properties private and just initialize them via constructor your deserializer would not know how these properties should be mapped to your backend (DTO) model.
Therefore, when working with DTOs, you usually don't see people initializing via constructor.
Also, since you are using your Price class throughout your code, you are mixing your "domain model" with your "view model" (= the model you use to communicate with the client) – which is a pragmatic approach but not advocated in styles like DDD. In such a case, if you want different properties or different access modifiers on your properties, you should create a dedicated PriceDTO that maps to your Price entity but has public setters and getters.
Another option would be to separate the model used by the endpoint that sends data to the client (via GET) from the model that is used by the endpoint that receives data as payload to create or update things (via POST/PATCH/PUT). However, this often comes at the cost of redundancy as the models in both cases are often highly similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With