Using Breeze for arbitrary server response - breeze

Have all a structure for creating complex queries and obtaining data on the client side using Breeze and webapi IQueryable<T>.
I would use this structure on the client side to call another webapi controller, intercept the result of the query, and use this to make an Excel file returned by HttpResponseMessage.
See: Returning binary file from controller in ASP.NET Web API
How can I use the executeQuery without getting return data in standard Breeze JSON and without interfering with the data on the client side cache to have the 'octet-stream'.
The goal is to create an 'Export to Excel' without existing frontend paging for a large volume of data.

If you don't want to track changes, call EntityQuery.noTracking() before calling executeQuery(). This will return raw javascript objects without breeze tracking capabilities.
You can't make executeQuery() return binary 'octet-stream' data. But you can use breeze ajax implementation:
var ajaxImpl = breeze.config.getAdapterInstance("ajax");
ajaxImpl.ajax() // by default it is a wrapper to jQuery.ajax
Look http://www.breezejs.com/documentation/customizing-ajax

Create a custom "data service adapter" and specify it when you create an EntityManager for this special purpose. It can be quite simple because you disable the most difficult parts to implement, the metadata and saveChanges methods.
You don't want to cache the results. Therefore, you make sure the manager's metadata store is empty and you should add the " no caching" QueryOption. [exact names escape me as I write this on my phone].
Make sure these steps are really adding tangible value
Specialized server operations often can be performed more simply with native AJAX components.
p.s. I just saw #didar 's answer which is consistent with mine. Blend these thoughts into your solution.

Related

Get another Entity while processing an Entity

I'am new in Olingo: sorry if my question is strange.
When Olingo service receive request to get entity of EntitySet_1 it calls method of custom entityProcessor (then processor call some storage object and send to it EdmEntitySet and List objects). But this processor method must get entity of EntitySet_2 to end processing. How i can realize getting entity of another entitySet? Or in other words: how can i get entity of another entitySet programatically (is it necessary to create new EdmEntitySet object? etc.) ?
Maybe some ideas, clever words...
Found only one solution: REST-request to the same service for entity of EntitySet_2 while processing entity of EntitySet_1.
Such feature should comes from the design itself. Calling same service from itself is not recommended.
What you should do is utilize the data access methods (ex:- database access method) you already have and get the required EntitySet_2 from it for processing.
For this you will need to create data access requests (ex:- SQL query for EntitySet_2) and map the results to create the EntitySet_2. As I said earlier, the design of your service should be flexible enough for this.

breezejs + entity framework: how to round-trip ad-hoc properties

I'm using breezejs with an entity framework 5 model. The model is the old-school edmx/objectcontext style- not the newer dbcontext/poco style.
The model is shared with some wcf ria services domain services so I cannot switch to entity framework 6 or poco style entity framework at this time.
When using wcf ria services, if you wanted to add a property to an entity beyond what is generated by entity framework you could create a partial class, define the property and annotate it with the datamember attribute. Wcf ria services treats this new property like any other property and sends it to the client from the server and back to the server.
Is there a way to do the same thing with breezejs? Without moving entirely away from the automatic metadata generation goodness that comes with using entity framework?
Using fiddler I can see the property I want exposed is transmitted to the client during a query request.
I've looked at the documentation here http://www.breezejs.com/documentation/extending-entities but none of the examples seem to fit this scenario.
Breeze supports unmapped properties, these are properties that are declared on your javascript constructor that cannot be matched to any property in metadata. By default these properties are both persisted locally and sent to the server on a save. This is described in the link you mentioned:
http://www.breezejs.com/documentation/extending-entities
var Customer = function () {
this.myUnmappedProperty = "anything22";
};
myEntityManager.metadataStore.registerEntityTypeCtor("Customer", Customer);
These values will be available on the server after a SaveChanges call via the 'UnmappedValuesMap' property on each EntityInfo instance.
var unmappedValue = entityInfo.UnmappedValuesMap["myUnmappedProperty"];
What is sounds like you are looking for is "unmapped" properties to go in the "other" direction, i.e. from the server to the client. What might work for that but we haven't tried is adding a property to your server side EF class ( via the partial class mechanism) and mark it up for Json serialization. It "should" then get serialized down to the client, even though it won't show up in Metadata.
If this does NOT work, please post back here and we will consider it as a breeze feature request. The basic idea does make a lot of sense and we should support it.

how to manage lifetime of variable for multiple request

I have a variable in create method in controller ,is there any way to reuse that variable with the same value in update method. How can i pass this, or how can i maintain the lifetime for the multiple requests?
Example variable:
#m = Issue.where( :project_id => #project.id ).where( :issue => "xyz" )
As I understand it, your requirement is to re-use data that was accessed during one call to your API (for creation of an API entity), during a separate call (an update). The data is fetched from the database in the first case.
Just fetch the data again, using the same query.
The database is the only data source easily accessible in both events, that will reliably hold an up-to-date value.
As this is for a RESTful API, there should be no other state information - everything should be in either the current request or the database.
If you want, you can cache data for performance, but Ruby variables are not a reliable or efficient way to do that (because there will be several Ruby processes running independently on the web server, and you don't get to manage them from the controller code) - instead you might want to consider something like memcached if the query is slow and its results are needed in many API events. However, you should normally avoid caching data except where you have a real performance issue - because you will probably need to handle cache invalidation, too.

Breeze and RESTful WebAPI

Question:
What value does breeze provide when I need to implement my own POST/PUT/GET endpoints per entity in WebAPI?
Background:
This seems to be a common implementation of a serverside Breeze controller:
[BreezeController]
public class TodosController : ApiController {
readonly EFContextProvider<TodosContext> _contextProvider =
new EFContextProvider<TodosContext>();
// ~/breeze/todos/Metadata
[HttpGet]
public string Metadata() {
return _contextProvider.Metadata();
}
// ~/breeze/todos/Todos
// ~/breeze/todos/Todos?$filter=IsArchived eq false&$orderby=CreatedAt
[HttpGet]
public IQueryable<TodoItem> Todos() {
return _contextProvider.Context.Todos;
}
// ~/breeze/todos/SaveChanges
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle) {
return _contextProvider.SaveChanges(saveBundle);
}
// other miscellaneous actions of no interest to us here
}
I'm in the middle of building a RESTish API that, up to this point, has endpoints like:
GET /api/todo/1
PUT /api/todo
POST /api/todo
It seems like Breeze requires the endpoints to be much simpler (for better or worse) - just a bunch of GETS and a SaveChanges POST endpoint.
This leads me to think that Breeze makes rapid development with a single web client, well, a breeze... but as soon as you have anonymous clients, you have to force them into whatever breeze interface conventions you've created in your client, which seems to defeat the purpose of RESTful API design. Is this the case?
Breeze is, first and formost, a client-side JavaScript framework. If you're not using Breeze on the client, the benefits of Breeze.WebApi are limited to
Enhanced OData query support ($select and $expand support, extended $orderby)
Save interception points (beforeSaveEntity and beforeSaveEntities events)
Save result handling (updated entity keys, concurrency columns)
Metadata extraction and serialization
As you've surmised, Breeze has a different philosophy from REST regarding CRUD operations.
Breeze is designed for clients who may want to C/U/D many resources, of different types, in a single transaction. This allows users to manipulate the data in complex ways without hitting the server, then saving their changes when they are ready. For example, one could create a new Order, move two OrderLineItems from one Order to another, delete a third OrderLineItem, modify the quantity on a fourth, and then SaveChanges(). Breeze even supports using localStorage to work completely disconnected from the server. Once reconnected, the changes can all be saved.
REST was designed to operate on one resource at a time. Each C/U/D operation must be performed against the server immediately so that the response code can be acted upon. It works well for applications with simple update needs, but not for data-entry applications. While transactions can be supported in REST, they are cumbersome at best.
Having said that, your server-side Breeze API is not limited to what you see in the Todos example. Breeze supports Named Saves, which allows you to have different endpoints for different operations. You can also use Save Interception to ensure that your save bundle only contains the types that it should. And naturally, there's nothing preventing you from exposing both APIs on your server, and having both fed by the same persistence layer.
If you have to decide between them, you should start with your users. Real users (not developers) don't care about REST, they care about what the application can do. Ultimately, REST gives your application all the semantics of HTTP, and Breeze gives it all the semantics of a relational or object database. Which one to expose to your users should depend upon the use cases you need to support.

db level ACL filtering

I am looking at Spring-security 3.0 for this, spring's ACL filtering happens as post(api call) operation. There are 2 issues with that :-
it will break paginated query
Even if i take pagination out on layer above the api fetching results( i am using spring-hibernate here) , the db query each time is wasteful as it fetches and populates all results even if most of them are destined to be filtered out at java level
I have seen solutions where each query is appended with the acl queries which does the filtering at the db level , but that looks ugly as it pollutes business logic with authorization concern, are there any ways/frameworks that does db-level acl filtering transparently ? I like spring-securities overall approach of enforcing security declaratively through config/annotations thus sparing the code from security related logic directly, but i think it loses out on this on performance concerns
For the issues that you mentioned , only the #1 one is the real issue to me .
For the #2 issue if I understand correctly , it is the query that return a result list without any pagination behaviour. Because of that , it is supposed to assume that size of the result is finite and will not grow to the point that it will become very slow to return the result . Otherwise you need to make this query to be pageable and go back to the #1 issue. Given the finite result list , I doubt that filtering at the application level using #PostFilter will become noticeably slower than filtering at the database level.
I have seen solutions where each query is appended with the acl
queries which does the filtering at the db level , but that looks ugly
as it pollutes business logic with authorization concern, are there
any ways/frameworks that does db-level acl filtering transparently ? I
like spring-securities overall approach of enforcing security
declaratively through config/annotations thus sparing the code from
security related logic directly,
So for the #1 issue , if you are using Hibernate , you can check out #Filter which allows you to declaratively define a where clause that will be appended to the select SQL when querying certain entity. The filter is by default turned off and required to be enabled per transaction .The where clause can also be parameterised .
That means you can simply use Spring AOP to define an annotation to annotate the query method that you want to enable the authorization .Then in the advice that backed by this annotation , turn on this filter and configure the parameters for the where clause based on the current user information if necessary. For the query method that is not annotated with this annotation , the filter is turned off and not aware of the authorization concern.
Basically it is the same as appending the authorization logic to the query , but with the help of AOP and the nature of the #Filter , the business logic is not aware of any authorization logic.
If Hibernate filter is not suitable for your requirements, you can then look into which data access technologies allow you to modify the query easily by adding the authorization logic to it. For example , using JPA Criteria API is also possible as it provides the object model to represent a query ,and hence adding the authorization logic to the query is just equivalent to tweaking the query object.
The idea is that you need to have a proper design of the data access layer such that you can use AOP to configure the underlying technology to apply the authorization concern easily and in a consistent way. And use AOP to separate the authorization logic from the business logic.

Resources