I have these fields marked as required in my yaml file (swagger spec)
MyType:
type: object
required:
- name
- amount
I am using swagger codegen maven plugin with these configurations:
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.2.3</version>
<language>spring</language>
<library>spring-mvc</library>
I would like to have required fields in spec to be made required in the generated classes as well. But that is not happening currently.
Are there configuration options to do that? I have <useBeanValidation>true</useBeanValidation> but this does not seem to work for me.
I saw a similar request enforcement of "required" fields in Definitions on Swagger-codegen GitHub page where suggestion was to use useBeanValidation and I do have it but it still does not work.
Created this request on Swagger-codegen GitHub page: Swagger-codegen enforcement of “required” fields in generated model classes
Found the solution. It was actually my mistake; I was expecting the field in the generated class to be marked required. It is rather the getter method which is annotated with #NonNull and required = true which solves the purpose. And now with the validation in place, I am able to see the validation is triggered and showing the message Amount should be present when amount is not passed in the request payload.
#ApiModelProperty(required = true, value = "Amount should be present")
#NotNull
public Amount getAmount() {
return amount;
}
Related
I'm trying to create a code wrapper for an api with NSwag and Autorest.
Previously I was using Swashbuckle to generate the swagger file. It generated the swagger file with operationIds in the format actionMethod. This resulted in Autorest generating a code client that was 1-deep. All of the actions were on the top-level class.
For various reasons, I needed to change swagger generation to NSwag. This generates operationIds in the format controller_actionMethod. This results in AutoRest creating a composite class that exposes separate classes with actions for each controller.
How can either
Change how NSwag generates the operationIds
Change how Autorest maps operationIds
Note: I know I can manually change the swagger.json, but I'd like to keep a consistent automated process for generating the code client.
There doesn't appear to be any readily available settings, but you can hook into the generation process of NSwag
https://github.com/RicoSuter/NSwag/wiki/Document-Processors-and-Operation-Processors#operation-processors
The operation processor
class FlattenOperationsProcessor: IOperationProcessor
{
public async Task<bool> ProcessAsync(OperationProcessorContext context)
{
context.OperationDescription.Operation.OperationId = $"{context.MethodInfo.Name}";
return true;
}
}
Then add it in Startup.cs
document.OperationProcessors.Add(new FlattenOperationsProcessor());
Not sure if this was available when the question was asked, but here is a pretty easy way to do it:
services.AddSwaggerGen(c =>
{
...
c.CustomOperationIds(d => d.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor ? controllerActionDescriptor.MethodInfo.Name : d.ActionDescriptor.AttributeRouteInfo?.Name);
});
The same can also be set via c.SwaggerGeneratorOptions.OperationIdSelector
Note that ActionDescriptor.AttributeRouteInfo?.Name is the default I used from the source code here
When I use generate-all package.DomainObject, it generates a controller where create action is generated as:
def create() {
respond new DomainObject(params)
}
When I call the localhost:8080/DomainObject/create even without making any code change, it throws an exception:
groovy.lang.MissingPropertyException: No such property: controller for
class: package.DomainObject
It looks like introspection is failing for properties that params map has and DomainObject does not have. This is surprising because in the grails 2, introspection used to just ignore the non-matching properties and it also used to do necessary type conversions on fields as well (now if DomainObject has an int property, it will throw a type mismatch exception because params map passes it as String). This is really inconvenient. Did something change or I am missing something?
Using the map constructor and setting properties in bulk with a map in Grails is basically the same as in Groovy, but it has logic to exclude 'controller', 'action', and 'format' keys to keep controller code like this uncluttered. That broke in 3.x and has been reported in the issue tracker. It's not marked fixed but works correctly for me in a simple 3.0.4 test app.
As a temporary workaround you can copy the params map and remove values stored under those keys and use the 'fixed' map for the constructor:
def create() {
def fixedParams = ([:] + params) // copy
['controller', 'format', 'action'].each { fixedParams.remove it }
respond new Thing(fixedParams)
}
Wondering if anyone knows of any way to extend or configure Breeze so that the server returns additional info in the entity metadata? I'd like to use this additional data to assist with validation.
Assume I have an entity model like so with some Data Annotations applied:
public class Person {
[RegularExpression(#"^$|^http\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?",
ErrorMessage="The Website address does not appear to be valid.")]
public string Website { get; set; }
[Required(ErrorMessage="The Name field is required."),
MaxLength(150, ErrorMessage = "The Name field cannot exceed 150 characters."),
MinLength(5, ErrorMessage = "The Name field must be at least 5 characters.")]
public string Name { get; set; }
//...
}
Right now, Breeze only hooks up a MaxLength and Required Validator based on the metadata it receives since this is all it supports out of the box. If Breeze could include in the metadata the info described in the Data Annotation Attributes on the server entity, I'm thinking it would then be possible for Breeze to automatically add additional stock validators to the client EntityType (e.g. for RegEx, Range, MinLength, etc... ). This would cover the majority of basic validation use cases. Or, it could also allow developers to inspect the metadata and pull out useful info like the regEx string which we could use to hook up our own custom RegEx validator.
Also, is there any way to have Breeze include the value of the ErrorMessage validation attribute property in the metadata and then have the breeze client use that instead of the default required and maxLength messageTemplates? This would mean you would only have to define the error message in one place on the server and wouldn't have to customize it for each entity.
I'm trying to avoid having to create and register a bunch of custom validators on the client for what seems like basic validations that could be handled by Breeze automatically.
Thanks,
Richard
It's a great question.
We haven't yet done a good job of documenting how the server serializes metadata but this should be coming "real soon now". However, if you take a look at the json coming over the wire you'll notice that validators are serialized simply by name. This name is then looked up among the registered validators ( or validator factories) on the client and then added to the client side metadata. So the idea would be to register you validator "implementation" on the client with a unique name, and then have the server reference this name when sending metadata down from the server.
Hopefully this will be clearer in a week or so once we have documented how to create your own server side metadata to send down to the client.
Hmmm, one year has passed. Any news on this topic? I fully agree with RWHepburn that defining all validation rules on the server-side and have it available in breeze on the client side would be a perfect thing. This is what data annotations in EF are for - making it easier!
I wrote a very simple test case and found that Grails does only a shallow validation when i call validate on a domain object. Is it possible for me to do a deep validation in grails? Can anybody help me?
class Person {
Address address
}
class Address {
String city
}
When i do new Address().validate() it returns false but when i do new Person(address: new Address()).validate it returns true.
While "deep validation" currently isn't documented for the validate() and save() methods, it will be in future (the document states that the documentation has been missing, while being relevant for the complete 1.3.x tree). The documentation on these methods' deepValidate parameter then will state:
#deepValidate# (optional) - Determines
whether associations of the domain
instance should also be validated,
i.e. whether validation cascades or
not. This is #true# by default - set
to #false# to disable cascading
validation.
Tests, however, show that "deep validation" is not performed in any of these cases:
one-to-one associations
one-to-many associations
associated objects assigned using the matching setter
associated objects assigned using the matching addTo*(..) method, e.g., person.addToAddresses(..)
using both the validate() and save() methods,
and also, using both methods with an explicit deepValidate: true parameter
Similar findings have been published at another place, categorizing the "non-behavior" as a "known issue". My own, comprehensive, test cases can be downloaded from here.
The solution, finally, is to manually invoke validation on the child object:
class Person {
Address primaryAddress
static hasMany = [secondaryAddresses: Address]
static constraints = {
primaryAddress validator: {
it?.validate()
}
secondaryAddresses validator: {
it?.every { it?.validate() }
}
}
}
In my ViewModels I use several DataAnnotations to validate the form data, there are usually 2-3 annotations per field.
For example a field for an email address might look like this:
[Required(ErrorMessage = "Please enter an email address.")]
[Email(ErrorMessage = "That is not a valid email address.")] // Custom
public string Email { get; set; }
Now if someone were to submit the form, both errors would show up in the validation summary. Is there any easy way to specify an order to run the validation annotations so that if the Required validation fails, the Email validation doesn't run?
If this isn't possible, how is this usually handled? Should I create custom validators for any field that has more than a single annotation? Would that be a proper way to use annotations, where a single one handles multiple types of validation?
(I'm also aware I could probably combine the Required annotation into the custom Email one, but this is just an example).
In this specific case I would probably take the same approach that the ASP.NET WebForms validators take - simply have the EmailAttribute validator return true if the value is null or empty.
Think about it:
If the e-mail address is required, then there will also be a [Required] validator and a null/empty e-mail address will generate a validation error anyway;
If the e-mail address is optional, a null/empty value should be considered valid.
No need to solve the complex problem of intercepting validators when you can just design the individual validators to play nice together!
Ordering validation: No.
In this case you could simply remove the Required attribute because "" or " " will fail the email address validation.
And yes, AFAIK creating a custom validation attribute that combines both of them is probably your best bet.
The problem here is that the ordering on the attributes is completely arbitrary and decided at compile time. You actually can enforce simple ordering depending on the kind of validation runner you're using. If you are using something like xVal and a validation runner like the one mentioned here, you can add an orderby clause like this to force a specific kind of attribute to sort to the top:
orderby attribute.GetType() == typeof(T) ? 0 : 1
Just make a strongly-typed validation runner method, where T is derived from the ValidationAttribute class.