grails - I need to define my validation at runtime - validation

I have an idea to read an XML document from the database and generate simple CRUD screens (via Grails) based on the data defined. My application will call RESTFul services to persist the data so I don't need Hibernate on the client side. I have ideas about how to generate the UI but where I'm stumped is in how to perform the validation.
I'll have a single, generic domain/command object that contains only the fields that are common for all instances of this "runtime" data type. All other fields are defined via the XML found in the database. I need something like this:
String xml // defines the fields, constraints, UI information for this data type
def constraints = {
callMyCustomValidator(obj)
}
and in my callMyCustomValidator method, I'll extract the xml for obj and perform my validation as needed.
Note: We have a working example of this in a different app (written in java/servlers/jsp) and without any formal "framework" this isn't difficult to do. Why do I need this? We need to add simple datatypes on the fly (via script) without a release.

You can use the validator to add custom validation to your domain class. Just add this to some of your common fields.

Related

Api Platform - returning data from external API

I'm currently using API Platform to display some data in Elasticsearch. This works fine, but I now have another feature that I'm looking at.
My application needs to deal with a 3rd-party API that needs to hit an endpoint and return some data.
Within my app, I'd like to be able to hit (/api/logistics/{action} - where action is an endpoint, such as login) and this then hits my app layer and returns data (3rd-party can be re-named)
The API calls to the 3rd party are fine, but I'm unsure how to display the response.
I've seen https://api-platform.com/docs/core/data-providers/ which looks like i can create a custom response.
Do i still need to create an entity/model and configure the #ApiResource() with a controller that uses my Data Provider?
If so, then what do i need to add in my annotation, since I won't have an id identifier
I'm fairly new to API Platform and I've not used the Data Provider functionality before
I will not be storing the data from the 3rd party API, just doing a HTTP call, retrieving the response and hopefully displaying it via Api Platform
Thanks
You are mosly right about the dataprovider. But as the docs page General Design Considerations states, "you have to write a plain old PHP object (POPO) representing the input and output of your endpoint. This is the class that is marked with the #ApiResource annotation. This class doesn't have to be mapped with Doctrine ORM, or any other persistence system."
So no, it does not need to be an Entity, but there must be a class marked with the #ApiResource annotation (but putting it in the Entity folder may help to make the #ApiResource() tag work - or adding the folder of your class in api/config/packages/api_platform.yaml).
For an item "get" endpoint your POPO needs an id. The poperty - or if there is only a getter, the getter - must be marked with the #ApiProperty(identifier=true) tag. Usually the easiest way to make one is by imploding/encoding some strings from the response of the external api call that together are unique for the response and will not change. Your dataprovider will have to explode/decode the id and use the components to make the external api call.
For a "post" operation you need a datapersister instead of a dataprovider. Apip will instatiate and populate your POPO and pass it to the datapersister and from there you can make the call to the external api and return an object as the result. If your object is not the same type of POPO you should specify "output"=TheOutputClass::class or put the operation on the output class and specify "input"=TheInputClass::class (replace TheOutputClass or TheInputClass by the actual class name)
For "put" and "patch" you need both a dataprovider, a datapersister and an id. They can have different input and output classes, see the docs about DTOs.
A collectionoperations with method "get" may seem convenient because you can just pass it any query string but your CollectionDataProvider must return an iterable.

Suggested way to prohibit certain attributes on create in Spring Data REST?

Spring Data REST has been working exceptionally well for me, but I need to be able to restrict what parameters the user may provide when creating certain resources. For instance, the user should not be able to dictate the ID assigned to the created resource or the activation state of an account, let's say.
My approach to this so far is simply to clear or reset these fields manually in a repository #HandleBeforeCreate event handler. Is there another, more clever option for restricting the accepted POST data for a resource?
Additionally, there are cases where a CRUD call needs to specify additional, contextual attributes that are not explicitly part of the target resource but may be used in the process of creating the resource. What is the appropriate way to handle this case?
You can define a custom validator by implementing org.springframework.validation.Validator and override validate(Object object, Errors errors) and validate the input fields and then populate or make necessary changes to the fields as required to the input request object.
You can refer here for more details and also here for an example.

Groovy pass request params between classes

If I want to handle many parameters from for example a web request and pass it between classes (layers) - what is the preferred way?
I know it is easy to pass optional numbers of parameters through the constructor as a map.
I can also pass a map directly and if the keys match the receiving objects property names it should work in a similar way
Or I could just pass the map and then instantiate for example domain classes from that
I could use a special class as data carrier with given number of properties
I have a domain class (not database domain but business domain) that needs data from the user interface.
What is the best way to pass data through the layers and how do I know that all required data is being passed if using a data structure - like a map - with key values? If I would have a more static constructor with a given number of parameters, then I would know that the parameters are being passed. But how do I secure this when using a more dynamic approach? With unit tests?
Well in Grails command objects are an excellent choice. You can pass them up to various layers without issues. They are pretty analogous to domain classes, only without the whole persistence functionality.
Otherwise I would recommend using plain old Groovy classes (POGOs). Groovy allows you to keep your code very short (compared to Java and many other languages as well) and offers very handy transforms for common design patterns you might need (e.g. Canonical, Immutable, IndexedProperty, DelegatesTo...).
Compared to command objects POGOs do require you to write e.g. validation code by yourself, but this can be as simple as
boolean isValid() {
name && lastName && countryCode in ['US', 'CA']
}
You can keep static factories in a POGO to help you construct them in the various circumstances. Plus you can define more than one class in a file so you can keep the POGO code wherever it makes most sense. I would definitely prefer this approach to simple maps because the code is better encapsulated, POGOs can be unit tested & documented.

Is there any simple way to validate field length with squeryl?

I'm using squeryl with playframework, and defined some entifies:
case class User(name:String, age:Int, ...) extends KeyedEntity[Long] {
val id = 0
}
The length of name field defined as varchar(50) in database.
Since we need to validate the values such as name before saving to database, I have to validate them manually:
checkLengthOf(user.name, 50);
If there are a lot of more fields, I need to do a lot of validation manually:
checkLengthOf(user.field1, ???);
checkLengthOf(user.field2, ???);
checkLengthOf(user.field3, ???);
checkLengthOf(user.field3, ???);
checkLengthOf(user.field4, ???);
I want to know is there any simple way to do this?
When I was in Java, there are some orm frameworks provide some annotations to do the validation automatically, can I do the same with squeryl?
Squeryl itself does not provide validation. It is purposely designed to only do what is necessary to be a very effective DSL for interacting with your database.
If you really want to automate this though, you could do it yourself. Squeryl 0.9.6 (which is at RC2 at the moment) provides life cycle callback methods which you could use to plug in your own validation logic. It isn't documented yet but you can see some examples In the tests.
Since Squeryl makes use of POSOs, which compile to regular Java objects, you could even use this to plug-in Java libraries like hibernate-validations..... if you really wanted to.
I don't know how you're receiving your updates, but one other thing to check out might be lift-squeryl-record. It allows you to define your fields as objects along with their validation logic. Record also integrates with Lift's CRUD generation and LiftScreen which is a pretty powerful tool for defining forms along with validation and processing logic.

Best way to represent object views (summary, detail, full etc) in Spring based REST service

I am working on a REST service which uses Spring 4.x. As per a requirement I have to produce several different views out of same object. Sample URIs:
To get full details of a location service: /services/locations/{id}/?q=view:full
To get summary of a location service: /services/locations/{id}/?q=view:summary
I have thought of two solutions for such problem:
1. Create different objects for different views.
2. Create same object, but filter out the fields based on some configuration (shown below)
location_summary_fields = field1, field2
location_detail_fields = field1, field2, field3
Could someone help me to understand what could be an ideal solution? I am not aware of any standard practice followed for this kind of problems.
Thanks,
NN
In my opinion the best option is to use separate POJOs for different views. It's a lot easier to document it (for example when you use some automated tools like Swagger). Also you've to remember that your application will change after some time, and then having one common POJO could make troubles - then you'll need to add one field to one service and don't expose it through another.
See this article on how google gson uses annotations to convert a Java Object representation to a json format : http://www.javacreed.com/gson-annotations-example/
Since you want two different representations for the same object you could roll your own
toJson method as follows :
a) Annotate each field of you model with either #Summary, #Detail or #All
b) Implement a toJson() method that returns a json representation by examining the annotations for the fields and appropriately using them
If you need an XML representation same thing, except you would have a toXML().

Resources