I am modelling an API with RAML and I am wondering if it’s possible to model dependencies between a query parameters.
Let’s say we’ve got a collection of objects. A user can narrow the query results down by specifying an object type and a state. Here’s a bit of RAML that should do what I just said:
/objects:
- searchable:
queryParameters:
object-type:
enum: [Type1, Type2, Type3]
object-state:
enum: [State1, State2, State3]
Now above definition may make the users feel that it's possible to use any combination they want - what is not quite right, as:
- object of 'Type1' can take just 'State1',
- object of 'Type2' can take 'State2' and 'State3',
- object of 'Type3' can take 'State1', 'State2', 'State3'.
Does anyone know how to model that with RAML?
AFAIK that's not possible in RAML. RAML is intended to describe an API, and that is more oriented to be business logic.
Nevertheless, I've heard about this question from a lot of people, and I think that it could be treated in RAML 1.0
Cheers!
Related
I am new to NestJs and GraphQl, I am learning going over some tutorials. It appears to be an inconstancy in the usage of the terminology model or entity. The nestjs schematics resource generator for graphql code first produces entities, yet the example shown on their website use models.
produces entities:
nx generate #nestjs/schematics:resource generated --language=ts --type=graphql-code-first
uses models no mention of entities in code first approach
https://docs.nestjs.com/graphql/resolvers
which one terminology is most appropriate?
Thank You,
Michael
Both are generally correct. It comes down to naming preferences.
I view entities as database entities, or database table maps. They map from your database data to a class representation that your code will understand. Models can also be used for this, which I believe is the term that sequilize and mongoose prefer to use.
Models, as described in the docs you linked, are generally your DTOs, your schema objects that you expect the API to accept and respond with.
You'll notice that the generator also generates two #InputType() files as well, which will be more closely tied to your incoming DTO while the entity.ts will be closer to your response DTO.
So, both are correct, and it comes down to naming preferencec.
When someone talks about hydrating an object, what does that mean?
I see a Java project called Hydrate on the web that transforms data between different representations (RDMS to OOPS to XML). Is this the general meaning of object hydration; to transform data between representations? Could it mean reconstructing an object hierarchy from a stored representation?
Hydration refers to the process of filling an object with data. An object which has not yet been hydrated has been instantiated and represents an entity that does have data, but the data has not yet been loaded into the object. This is something that is done for performance reasons.
Additionally, the term hydration is used when discussing plans for loading data from databases or other data sources. Here are some examples:
You could say that an object is partially hydrated when you have only loaded some of the fields into it, but not all of them. This can be done because those other fields are not necessary for your current operations. So there's no reason to waste bandwidth and CPU cycles loading, transferring, and setting this data when it's not going to be used.
Additionally, there are some ORM's, such as Doctrine, which do not hydrate objects when they are instantiated, but only when the data is accessed in that object. This is one method that helps to not load data which is not going to be used.
With respect to the more generic term hydrate
Hydrating an object is taking an object that exists in memory, that doesn't yet contain any domain data ("real" data), and then populating it with domain data (such as from a database, from the network, or from a file system).
From Erick Robertson's comments on this answer:
deserialization == instantiation + hydration
If you don't need to worry about blistering performance, and you aren't debugging performance optimizations that are in the internals of a data access API, then you probably don't need to deal with hydration explicitly. You would typically use deserialization instead so you can write less code. Some data access APIs don't give you this option, and in those cases you'd also have to explicitly call the hydration step yourself.
For a bit more detail on the concept of Hydration, see Erick Robertson's answer on this same question.
With respect to the Java project called hydrate
You asked about this framework specifically, so I looked into it.
As best as I can tell, I don't think this project used the word "hydrate" in a very generic sense. I see its use in the title as an approximate synonym for "serialization". As explained above, this usage isn't entirely accurate:
See: http://en.wikipedia.org/wiki/Serialization
translating data structures or object state into a format that can be stored [...] and reconstructed later in the same or another computer environment.
I can't find the reason behind their name directly on the Hydrate FAQ, but I got clues to their intention. I think they picked the name "Hydrate" because the purpose of the library is similar to the popular sound-alike Hibernate framework, but it was designed with the exact opposite workflow in mind.
Most ORMs, Hibernate included, take an in-memory object-model oriented approach, with the database taking second consideration. The Hydrate library instead takes a database-schema oriented approach, preserving your relational data structures and letting your program work on top of them more cleanly.
Metaphorically speaking, still with respect to this library's name: Hydrate is like "making something ready to use" (like re-hydrating Dried Foods). It is a metaphorical opposite of Hibernate, which is more like "putting something away for the winter" (like Animal Hibernation).
The decision to name the library Hydrate, as far as I can tell, was not concerned with the generic computer programming term "hydrate".
When using the generic computer programming term "hydrate", performance optimizations are usually the motivation (or debugging existing optimizations). Even if the library supports granular control over when and how objects are populated with data, the timing and performance don't seem to be the primary motivation for the name or the library's functionality. The library seems more concerned with enabling end-to-end mapping and schema-preservation.
While it is somewhat redundant vernacular as Merlyn mentioned, in my experience it refers only to filling/populating an object, not instantiating/creating it, so it is a useful word when you need to be precise.
This is a pretty old question, but it seems that there is still confusion over the meaning of the following terms. Hopefully, this will disambiguate.
Hydrate
When you see descriptions that say things like, "an object that is waiting for data, is waiting to be hydrated", that's confusing and misleading. Objects don't wait for things, and hydration is just the act of filling an object with data.
Using JavaScript as the example:
const obj = {}; // empty object
const data = { foo: true, bar: true, baz: true };
// Hydrate "obj" with "data"
Object.assign(obj, data);
console.log(obj.foo); // true
console.log(obj.bar); // true
console.log(obj.baz); // true
Anything that adds values to obj is "hydrating" it. I'm just using Object.assign() in this example.
Since the terms "serialize" and "deserialize" were also mentioned in other answers, here are examples to help disambiguate the meaning of those concepts from hydration:
Serialize
console.log(JSON.stringify({ foo: true, bar: true, baz: true }));
Deserialize
console.log(JSON.parse('{"foo":true,"bar":true,"baz":true}'));
In PHP, you can create a new class from its name, w/o invoke constructor, like this:
require "A.php";
$className = "A";
$class = new \ReflectionClass($className);
$instance = $class->newInstanceWithoutConstructor();
Then, you can hydrate invoking setters (or public attributes)
Requirements
generic query language that can be used in GET requests to collection resources in REST api to filter the set of resources returned
queries passed in via a "standard" query language and sent over HTTP as request parameter(s) - .e.g /someresource?query=...... or /someresource?a.b.c=2
SQL queries constructed at runtime on the server
tight integration with jpa, spring-data, spring-data-rest - the less code the better.
nested resource and attribute paths available for queries
support for complex operands - EQUALS, GREATER_THAN, LESS_THAN, NEGATION, LIKE, AND, OR, NOT, IN
E.g.
resourceA.attribute1 = "CAT" AND resourceA.subResourceB.attribute2 >= 42 AND resourceA.attribute3 IN ("WHIZ","BANG")
I've investigated four solutions - each getting closer to the goal. Is there some other solution I haven't found or is there no such complete solution out of the box - is the answer to build upon the "REST query language with RSQL" outlined below?
1) spring-data-rest queries
There is plenty of support in spring data for developing complex queries in code, however this requires the developer to be aware of the structure of queries beforehand and to construct the code accordingly.
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#repository-resources.query-method-resource
2) spring-data, spring-data-rest, query-dsl
http://www.baeldung.com/rest-api-search-querydsl-web-in-spring-data-jpa
+ve An excellent fit - thoroughly capable solution with almost zero coding out of the box
+ve deeply nested queries can be constructed and the server generates correct SQL on the fly.
-ve the only operator is EQUALS '=' in order to apply additional operators you need to implement QuerydslBinderCustomizer instances which once again requires the server code to be aware of the complexity of the query in advance.
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/querydsl/binding/QuerydslBinderCustomizer.html
3) Baeldung - "building a rest query language"
http://www.baeldung.com/spring-rest-api-query-search-language-tutorial
basic operations (EQUALS, GREATER_THAN, LESS_THAN)
http://www.baeldung.com/rest-api-search-language-spring-data-querydsl
advanced operations ((EQUALS, GREATER_THAN, LESS_THAN, NEGATION, LIKE)
http://www.baeldung.com/rest-api-query-search-language-more-operations
OR operator
http://www.baeldung.com/rest-api-query-search-or-operation
+ve - getting closer to generic query language
-ve - feels like a demo / POC
4) REST Query Language with RSQL
http://www.baeldung.com/rest-api-search-language-rsql-fiql
+ve - feels like a more complete Query language & associated parser
-ve - unsure of spring integration
There is no generic REST query language for JPA. What you've identified seems to be what is out there, however the low recent activity on querydsl and rsql suggests that you should use caution when adopting them. You will most likely have to support additional changes yourself by forking the projects, especially 5 years from now when for sure the author has moved on to other things.
Some other interesting links:
5) Use annotations to dynamically build queries
https://blog.tratif.com/2017/11/23/effective-restful-search-api-in-spring
maps annotations on a controller method via Spring's argument resolvers to JPA criteria specifications
places SQL concepts like joins in the web controller, which leaks abstractions
should be implemented at a service level not a controller level
I have been reading about specifications lately and I am really keen on using them. However, I am afraid to overdo it.
For example, if I have a User entity with a phone number property, do I need to put the phone number specification test in the setter, or is the validation logic in the setter enough?
Thanks,
Phil
UPDATE:
For more context:
I think I would like the validation to be in the domain, and not in the presentation. I will implement the validation in presentation, but that will be more of a UI feature. The idea (i believe) is that the domain cannot be in an invalid state, nor can it rely on the presentation. I actually have a phone number Entity, and many entities have phone numbers, though I suppose this could value object, but that is another debate:)
I was just wondering if it overkill to use Specifications in Property setters. One advantage I could see is that Specifications can be shared between layers, ie the Presentation Layer, so that you can share the validation code.
As you can see, I am unsure if this is the right approach.
Much Thanks,
Phil
You might look into the notion of pre and post conditions (invariants or design by contract).
Pre conditions are things that must be true for your function to operate correctly.
Post conditions are things that will be true when your function is complete and exits normally.
"user's phone number valid" is probably a good post condition to have for your setter function. However you have 2 choices for the pre-condition: (1) make it a precondition of your setter function that whatever is passed to it is valid, or (2) make a much looser pre condition to your setter function and perform the error checking in your setter function. Option (1) essentially passes responsibility for validation to the client. Option (2) endows your User entity with the responsibility for error handling.
I think the design you choose would depend on the bigger picture for your specific application.
Here are a few links for invariants and design by contract:
http://svengrand.blogspot.com/2008/11/preconditions-postconditions-invariants.html
http://en.wikibooks.org/wiki/Computer_Programming/Design_by_Contract
I'm looking at some code I've written and thinking "should I be passing that object into the method or just some of its properties?".
Let me explain:
This object has about 15 properties - user inputs. I then have about 10 methods that use upto 5 of these inputs. Now, the interface looks a lot cleaner, if each method has 1 parameter - the "user inputs object". But each method does not need all of these properties. I could just pass the properties that each method needs.
The fact I'm asking this question indicates I accept I may be doing things wrong.
Discuss......:)
EDIT: To add calrity:
From a web page a user enters details about their house and garden. Number of doors, number of rooms and other properties of this nature (15 in total).
These details are stored on a "HouseDetails" object as simple integer properties.
An instance of "HouseDetails" is passed into "HouseRequirementsCalculator". This class has 10 private methods like "calculate area of carpet", "caclulateExtensionPotential" etc.
For an example of my query, let's use "CalculateAreaOfCarpet" method.
should I pass the "HouseDetails" object
or should I pass "HouseDetails.MainRoomArea, HouseDetails.KitchenArea, HouseDetails.BathroomArea" etc
Based on my answer above and related to your edit:
a) You should pass the "HouseDetails"
object
Other thoughts:
Thinking more about your question and especially the added detail i'm left wondering why you would not just include those calculation methods as part of your HouseDetails object. After all, they are calculations that are specific to that object only. Why create an interface and another class to manage the calculations separately?
Older text:
Each method should and will know what part of the passed-in object it needs to reference to get its job done. You don't/shouldn't need to enforce this knowledge by creating fine-grained overloads in your interface. The passed-in object is your model and your contract.
Also, imagine how much code will be affected if you add and remove a property from this object. Keep it simple.
Passing individual properties - and different in each case - seems pretty messy. I'd rather pass whole objects.
Mind that you gave not enough insight into your situation. Perhaps try to describe the actual usage of this things? What is this object with 15 properties?, are those "10 methods that use upto 5 of these input" on the same object, or some other one?
After the question been edited
I should definitely go with passing the whole object and do the necessary calculations in the Calculator class.
On the other hand you may find Domain Driven Design an attractive alternative (http://en.wikipedia.org/wiki/Domain-driven_design). With regard to that principles you could add methods from calculator to the HouseDetails class. Domain Driven Design is quite nice style of writing apps, just depends how clean this way is for you.