Mirror formatting spring-data-rest/spring-hateoas in custom controllers - spring-data

I used the suggested approach in this question to return HATEOAS formatted outputs that match those returned by spring-data-rest. It works good, but is there a way to avoid boiler plate code to create entity resource assemblers like the QuestionResourceAssembler in the referenced question, if I only want to add 'self' links using the id to all entities? Perhaps using ResourceAssemblerSupport?

The easiest way is to simply use the Resource wrapper type:
Resource<Person> personResource = new Resource<>(person);
personResource.addLink(…);
personResource.addLink(…);
Links can be created either by simply instantiating them (i.e. new Link("http://localhost/foo", "relation") or by using the ControllerLinkBuilder which allows you to point to Controller methods for obtain a reverse mapping. See this section of the Readme for details.

Related

How to get an OrderedSet of OccurrenceSpecifications from a Lifeline in QVTo?

From the diagram on page 570 of the UML spec I concluded that a Lifeline should have the events property, holding an OrderedSet(OcurrenceSpecification). Unfortunately it is not there, at least in the QVTo implementation that I use.
All I have is the coveredBy property, serving me with an (unordered) Set(InteractionFragment). Since my transformation relies on the correct order of MessageOcurrenceSpecification I somehow need to implement myself what I expected to be implemented by the missing events property.
This is what I have so far:
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.coveredBy->selectByKind(OccurrenceSpecification)->sortedBy(true);
}
Obviously sortedBy(true) does not get me far, but I don't know any further. Who can help?
All I could find so far were other people struggling with the same issue years ago, but no solution:
https://www.eclipse.org/forums/index.php/m/1049555/
https://www.eclipse.org/forums/index.php/m/1050025/
https://www.eclipse.org/forums/index.php/m/1095764/
Based on the answer by Vincent combined with input from a colleague of mine I came up with the following solution for QVTo:
-- -----------------------------------------------------------------------------
-- Polyfill for the missing Lifeline::events property
query Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.fragment
->selectByKind(OccurrenceSpecification)
->select(os: OccurrenceSpecification | os.covered->includes(self))
->asOrderedSet();
}
I don't know if it is possible, using directly coveredBy to get an ordered collection. As coveredBy is unordered, if you access it directly by the feature, you will have an unpredictible order and if you try to access it using the eGet(...) stuff, the same result will occur.
However, if I understood correctly, there is a "trick" that could work.
It relies on the assumption that each OccurrenceSpecification instance you need is held by the same Interaction that contains the Lifeline and uses the way EMF stores contained elements. Actually, each contained element is always kind of 'ordered' relatively to its parent (and for each collection so EMF can find elements back when XMI references are expressed using the element position in collections). So, the idea would be to access all the elements contained by the Interaction that owns the lifeline and filter the ones that are contained in coveredBy.
Expression with Acceleo
This is easy to write in MTL/Acceleo. In know you don't use it, but it illustrates what the expression does:
# In Acceleo:
# 'self' is the lifeline instance
self.interaction.eAllContents(OccurrenceSpecification)->select(e | self.coveredBy->includes(e))->asOrderedSet()
with self.interaction we retrieve the Interaction, then we get all the contained elements with eAllContents(...) and we filter the ones that are in the self.coveredBy collection.
But it is way less intuitive in QVT as eAllContents(...) does not exist. Instead you have to gain access to eContents() which is defined on EObject and returns an EList which is transtyped to a Sequence (in QVT,eAllContents() returns a ETreeIterator which is not transtyped by the QVT engine).
So, how to gain access to eContents() in the helper? There is two solutions:
Solution 1: Using the emf.tools library
The emf.tools library give you the ability to use asEObject() which casts your object in a pure EObject and give you more methods to access to (as eClass() for example...etc).
import emf.tools; -- we import the EMF tools library
modeltype UML ...; -- all your metamodel imports and stuffs
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.asEObject().eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Solution 2: Using oclAstype(...)
If for some reason emf.tools cannot be accessed, you can still cast to an EObject using oclAsType(...).
modeltype UML ...; -- all your metamodel imports and stuffs
modeltype ECORE "strict" uses ecore('http://www.eclipse.org/emf/2002/Ecore'); -- you also register the Ecore metamodel
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.oclAsType(EObject).eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Limitation
Ok, let's be honest here, this solution seems to work on the quick tests I performed, but I'm not a 100% sure that you will have all the elements you want as this code relies on the strong assumption that every OccurrenceSpecification you need are in the same Interaction as the Liteline instance. If you are sure that all the coveredBy elements you need are in the Interaction (I think they should be), then, that's not the sexiest solution, but it should do the work.
EDIT>
The solution proposed by hielsnoppe is more eleguant than the one I presented here and should be prefered.
You are correct. The Lifeline::events property is clearly shown on the diagram and appears in derived models such as UML.merged.uml.
Unfortunately Eclipse QVTo uses the Ecore projection of the UML metamodel to UML.ecore where unnavigable opposites are pruned. (A recent UML2Ecore enhancement allows the name to be persisted as an EAnnotation.) However once the true property name "events" has been pruned the implicit property name "OccurrenceSpecification" should work.
All associations are navigable in both directions in OCL, so this loss is a bug. (The new Pivot-based Eclipse OCL goes back to the primary UML model in order to avoid UML2Ecore losses. Once Eclipse QVTo migrates to the Pivot OCL you should see the behavior you expected.)

API.AI Intent won't save when adding Required Action

I'm trying to create a chat bot that will help users search up motorcycles.
I'm new to API.AI and have set up my entities and their synonyms, my intent and user expressions, as well as references to the entities (#engineSize, #make, #bikeType).
My problem is when I try to add a required action and prompt, and then try to save the intent, I get the following message:
"The following entities reference each other and form an infinite loop: [engineSize]."
Initially I thought I was using the references wrong in the user expressions. I deleted every reference except for one expression which uses all three entities.
I can't figure out what I'm doing wrong. Any help would be greatly appreciated, thanks! Pix below for further details.
EDIT: I fixed one of the issues of trying to pass a template expression as an example. However, I still get the same error message. I will replace and update my image links to include the edits.
Annotated User expressions
Required Actions
Interestingly enough, the answer to this post would have been difficult to find because the problem was in defining my entities.
In the entity definitions, I included an #ref to the entity itself. ie the bikeType entity contained #bikeType as one of its definitions.
This is not to be mistaken with the User Expressions. As long as the user expression is marked as a Template (the entire line is denoted with an '#' on the far left, as opposed to a large " ), there should be no issues.
Edited for clarity to get at root problem
In the provided user input examples you give the intent, you are supposed to provide general examples and then highlight any text belonging to an entity to map where entities appear in user's inquiries.
In your case, you have input the actual entity reference '#engineSize' as an example belonging to the engineSize entity, creating a self reference.
A proper provided user example would look like:
Also note though that if you are just using entities to store generic information like numbers, addresses, times, etc. it generally makes far more sense to use prebuilt system entities for those categories than create a custom entity, for example #sys.number-integer might be exactly what you need
It looks like you need to get a firmer understanding of entities, for which I would recommend the documentation:
https://docs.api.ai/docs/concept-entities

REST - basic principles - Where to put the new and edit words

I'm wondering where to put the edit, and new keywords by rest application. I'll use express-resource in a project, and the default settings are these:
GET /forums -> index
GET /forums/new -> new
POST /forums -> create
GET /forums/:forum -> show
GET /forums/:forum/edit -> edit
PUT /forums/:forum -> update
DELETE /forums/:forum -> destroy
There is a problem with this solution: there is not a real resource behind the new and edit. I mean the URL-s refer to resources, and after any slash is a sub-resource.
For example:http://my.example.com/users/1 represents:
var firstUser = {
name: "John Smith",
birthDate: new Date(1952,10,4),
hobbies: ["skiing", "football"],
...
}
And http://my.example.com/users/1/birthDate represents:
firstUser.birthDate
But by http://my.example.com/users/1/edit there is no such property:
firstUser.edit
So something is wrong with this conception.
Where is the real place of these keywords? In queryString or in headers?
From the perspective of a REST API these do not exist anywhere as they are not related to the representation of resources. They are actions upon resources and therefore expressed by the HTTP methods used. They would not bee needed if you were to create an external client that uses the API.
There is likely a need to provide some support for this type of functionality so that something like a UI could be presented, but that is the concern of the particular application and not the API itself. At that point it becomes discretionary but I would certainly avoid using headers as that would be pretty outside of conventional practice. But by headers it appears that you actually meant URI path. Out of those 2 I would say the path is the better option since it clearly defines any type of UI as a distinct resource and would keep it apart from the clean API, while using a query string on a part of the API would more tightly (mistakenly) associate it with the underlying resource.
Some update after a year or so:
edit and new should be hyperlinks
these links are just the representations of possible operation calls
by following them it is possible to manipulate the resource they belong by sending representations of the intended resource state, and/or by calling the proper methods
these terms are no resources, they don't have their own URL (resource identifier)
Thanks the advices Matt Whipple!
I think the best way to learn REST is reading the Fielding dissertation. There are many tutorials out there, but the authors of most of these does not really understand REST.

WCF Data Service with EF fails to expose imported functions

(I am also using .NET 4.0 and VS 2010.)
I created a function import returning a complex type, as explained at http://msdn.microsoft.com/en-us/library/bb896231.aspx. The function import and new complex type appear in my .edmx file and in the Designer.cs file. However, the function does not appear when I view the service in the browser, and when I add or update a service reference in the client project, the function does not appear there either - as is to be expected, given the first result.
Creating an imported function and using it seems conceptually very simple and straightforward, and one would think it would just work, as Microsoft's step-by-step instructions appear to suggest: http://msdn.microsoft.com/en-us/library/cc716672.aspx#Y798 (which article shows the SP returning entity types - I tried this also, and it doesn't work for me either).
This blog post shows the addition of a method to the DataService class, which Microsoft's instructions omit: http://www.codegain.com/articles/wcf/miscellaneous/how-to-use-stored-procedure-in-wcf-data-service.aspx I tried adding one method returning a list of entity types and another returning a list of complex types, and still had no success. I still could not access the functions, either directly via the browser or from the client application via a service reference.
Thanks in advance for any help with this.
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
MS would do well to add a note to the walkthroughs stating that the above bit of code must be there. (It may be better to enable each operation explicitly than to use "*".)
http://www.codegain.com/articles/wcf/miscellaneous/how-to-use-stored-procedure-in-wcf-data-service.aspx shows that line of code. Also, something it is there in the code, commented out, when one creates the WCF Data Service. Some of us like to delete commented-out code that we aren't using and that seems irrelevant - perhaps doing so a bit prematurely, sometimes.

ReSTful design: return an empty object as a template for create new form

My question is straighforward - I think.
Currently the following Uris exist:
http://someserver/service/item GET returns all items
http://someserver/service/item POST creates a new item
http://someserver/service/item/{id} GET returns item with id {id}
http://someserver/service/item/{id} PUT updates item with {id}
What I would like to do is return a blank 'item', like a template for creating new items which contains a list of the object parameters, their types, required or not. The reason for this is I would like to build a generic jquery 'create new' plugin completely ignorant of the data structure, which I could apply to all my new objects.
What is the best way to implement this?
I hope this makes sense and thanks for your time.
I understand an answer provided by Darrel but I would respectfully argue against it.
It seems to me that this template object (resource) is an important part of your application because you want to make it generic. It's a first class citizen resource and we're talking about REST, so it should be given a corresponding treatment. I should be able to GET the template resource, it shouldn't be "hidden" behind POST.
GET http://someserver/service/item/template
Then you can also introduce versioning and variability much more easily when you have a resource accessible via GET.
I do pretty much the same thing. I include a link in my "list of items" resource that you can POST to. The response is a template of a new item. Arguably you could also do a GET to retrieve the template, but I use the opportunity to assign a new Id to the item so my request is not idempotent.