FOSElastica + FosRest + Doctrine + REST Api - rest

Versions
Symfony 2.8.2
FosElastica 3.1.8
FosRest 1.7.7
Doctrine 2.5.4
Problem
Hello,
I have some MYSQL's tables with many relations. I would like a build a REST Api, in HTMl a JSON, to get them.
It is working in HTML, but doesn't in JSON.
Indeed, in JSON I am returning array with multi dimensional, and doctrine made each request to get data.
This maneuver makes many times and fail.
The solution will be to make a SQL join with the return of ElasticSearch but I don't how to make that.
Any idea?

The better solution is to make a REST API.
REST API never reterning a deep JSON Object, but only the asked object.
For instance one Entity People containing a list of Cars.
You have to make routing something like that :
Returning all users as light object (only id ans very important informations) :
/users
Returning one Full User WITHOUT his cars :
/users/{userId}
Returning full list if cars (as light objects) :
/users/{userId}/cars
Returning full car object (without sub object obviously) :
/users/{userId}/cars/{carId}
After you can manage your routing as you want with RESTFull

Related

REST api desing. Retrieving and saving child records

I am designing a rest api and I have some doubts about exposing and consuming children from relation.
Assuming I have an entity A with a one to many relation to entity B (so A can have some Bs attached) and I design an endpoint to create entity A and DTO for entity A includes a list for entity B and user provides a valid one, should it be saved too?
Example:
Doing a post to some endpoint e.g. /api/v1/As
{
entityAfield1: someValue,
entityAfield2: someOtherValue
Bs: [
{
HERE a valid B payload
}
]
}
should I also save B and create a relation between A and B? What if B also have some children? Should it be saved too?
Or should I just save A and create an endpoint like
/api/v1/As/{Aid}/Bs/{Bid}
to create a relation?
And same question about getting data. Should get always retrieve all children? I couldn't find a clear answer to this on the web.
The issue might be solved by means of returning the IDs of Bs. This way, a user of service will decide whether or not to retrieve the actual data of related resources.
To interact with those an endpoint like this
/api/v1/Bs/{Bid}
can be used, as well as a more verbose one
/api/v1/As/{Aid}/Bs/{Bid}
however, the too nested endpoints, like
/api/v1/As/{Aid}/Bs/{Bid}/Cs/{Cid}/Ds/{Did}
should be avoided and most likely indicate a design flaw.
For a tree structure or many to many relations in general, an intermediate resource that represents a linkage should be exposed. There is a good example of a REST API implementation by Google, its "Children" section would be especially helpful for such case.

New DTO or Field Selector for API?

I am working on new API, but I am stuck with the choice for enabling Projection support.
my Entity User contains some properties and have some relationships too.
What should be the preferred approach for API?
Approach1
myApi.com/User/Fields="Id,Name,Email"
it returns my UserDTO with just populating Id,Name,Email and rest properties are null (I can further ignore the null before serializing JSON to send over the wire)
Approach2
myApi.com/User/GetCustomPropertiesABC"
it returns my UserCustomABCDTO . This Model contains just three properties for Id, Name, Email.
My question
I personally feel Approach 1 gives more Reuse quotient to API, Every time new selector required in Approach 2 will need to create a New DTO, But what is standard as per REST principles?
well, you could use ODATA for this, it would be perfect for it actually : http://www.odata.org/
Or, you could create an endpoint which accepts a request like your Approach 1 and returns dynamic. This way you don't have to worry about creating DTOs, you just create a new dynamic object, add whatever properties are required and return just that.
This keeps the returned entity small as it avoids who knows how many null or empty properties which don't really add anything useful.

Why is DELETE not supported on to-many-association resources in Spring Data REST?

I am using Spring Data REST. I am trying to unbind a collection association from an entity (item). i.e. - a property of the item is of List type. I want to remove all items from that List.
To do this, I am using the DELETE method:
curl -X DELETE …/categories/54ea0bcf27a2fb1b4641083a/fixedParentCategories
This gives me a 405 Method not allowed error code. But, it works for a single valued association (when it is not of List type). The documentation clearly lists DELETE as a supported method for associations. I'd like to know if there is a way around this. Also, I tried using PUT (Content-Type: text/uri-list) with an empty body, and it gives an error about missing request body. Other operations on this association are all working fine - I am able to add items to this collection, etc.
My entity looks like this:
#Document
public class Category {
#DBRef(lazy = true)
private List<Category> fixedParentCategories;
…
}
I just checked the code and you're right, we're actively rejecting DELETE requests for Maps and collections. The rationale is as follows:
An association that is of Map or collection must never be null in the domain model. Translating this into HTTP resources means that the resource will always be available and in the worst case return an empty representation (empty JSON array, or empty JSON object). Accepting a DELETE request would logically null the relationship in the domain model and thus lead to a state that contradicts the very first assumption.
We generally recommend to simply PUT an empty body with media type text/uri-list to the association resource to empty out the associations as that's semantically more correct. Consider it like the difference between truncating and dropping a database table.
If you think that should change and have good reasons that you can back your request with, feel free to open a ticket in our JIRA.

Where do you create a custom model (DTO) in server code, such that Breeze can relate to EntityFramework entities?

I am developing a SPA using Angular-Breeze-WebAPI-EntityFramework.
Now Breeze uses the Entity Framework metadata information to create it's own Breeze models. We use this in our application for Breeze validation.
So far, it's all been nice and easy. Now we are having to create a search page (say for querying customers). The search can be by Customer.Name or by Product.Id (which would return a list of customers who have bought that product). The result is a ng-repeater, which displays Customer.Name, Order.LastPlaced etc.
if you are getting confused by the tables and columns, forget that. What I am only trying to get to is that, both the search object and the result object are not 1:1 with Entity tables (or objects). So obviously I feel the need to create a custom object (one for the search and one for the results). My question primarily is where and how do I create that object?
If I create it at the data layer, Breeze would have no idea of the metadata for each of the properties (since it uses EF for that).
I obviously can't create just a JavaScript object, since I will have to query the database (using EF) to search and populate the object.
So where does one create such a custom object (traversing multiple tables) such that Breeze still can figure out the metadata and perform validation and such when the need arises?
Thank you all.
You can create metadata on the client for types that the server either doesn't know about or doesn't have the schema for. See http://www.breezejs.com/documentation/metadata-by-hand.

Dynamics 2011 Intersect / Junction entity

I have 3 entities.
PortalRole, Person and PersonPortalRole
PersonPortalRole is a intersection entity to deal with my Many-Many relationship.
I am using JavaScript through a HTML web resource to allow the creation and removal of this entity. I can create new entities by using the REST service fairly easily but I can't find a way of deleting a intersect record (two lookup fields) using the PersonId and PortalRoleId.
Has anyone had any exposure to either deleting a record through REST using the two foreign keys values from a lookup? I was trying to get the object first using a filter but can't seemt o filter using the lookup primary keys.
Was trying something like below which returns 15 entries to then filter the results to get the primary key, and then delete using that key but not sure on the way to do this.
SERVER/INSTANCE/XRMServices/2011/OrganizationData.svc/personportalrolesSet?$expand=Person,PortalRole
Based on that URI, you are interacting with an OData service. OData uses Atom feeds for returning lists of stuff so you will likely find within each <entry> element a <id> element that contains the URL of the resource. If you issue a HTTP DELETE to that URL then your resource will be deleted.
See docs here http://www.odata.org/developers/protocols/operations#DeletingEntries
I don't use the REST endpoint, but there's no way I know of to end a many-to-many relationship except through sending a Disassociate request (or if you have access to the SQL box, direct insertion/deletion in that table). MS has some sample code available that shows how to do this using the REST Endpoint.