PDA

View Full Version : [OBSOLETE]Content Header in Restful Webservices



Sgt.Pepper
7 Jun 2009, 3:10 AM
Hi,

I've been playing around with extjs for quite a while. First thing, I really want to thank the developers and the community for sharing such a great framework and your experience with us...

EDIT (I think i misunderstood the problem originally...)

Now I have a question: I have written a simple restful webservice, which uses JSON to encode the objects.
My ExtJs App can sucessfully GET the objects from the webservice. However, when I PUT them back to the server, It doesnt really work.
I think that Ext JS isn't sending the whole data in JSON, but rather as normal POST parameters with one parameter that carries the JSON string.

Is there a possibility to change this behaviour, and just PUT the plain JSON object back to the server?

Sgt.Pepper
7 Jun 2009, 6:10 AM
Hi again,

I found some kind of a solution, well actually it wasn't my own idea (thanks for the hint Chris).

The idea is, that the Ext.Ajax.request needs to get the "JSON" property filled, and not the "param". So I extended the HttpProxy, and overwrote the doRequest function: (actually just one single line changed...)



Ext.ux.PureJsonHttpProxy = Ext.extend( Ext.data.HttpProxy, {


doRequest : function(action, rs, params, reader, cb, scope, arg) {

var o = {

//params : params || {},
jsonData : Ext.util.JSON.decode(params.data) || '{}',

method: (this.api[action]) ? this.api[action]['method'] : undefined,
request: {
callback : cb,
scope : scope,
arg : arg
},
reader: reader,
callback : this.createCallback(action, rs),
scope: this
};
// Set the connection url. If this.conn.url is not null here,
// the user may have overridden the url during a beforeaction event-handler.
// this.conn.url is nullified after each request.
if (this.conn.url === null) {
this.conn.url = this.buildUrl(action, rs);
}
else if (this.restful === true && rs instanceof Ext.data.Record && !rs.phantom) {
this.conn.url += '/' + rs.id;
}
if(this.useAjax){

Ext.applyIf(o, this.conn);

// If a currently running request is found for this action, abort it.
if (this.activeRequest[action]) {
// Disabled aborting activeRequest while implementing REST. activeRequest[action] will have to become an array

//Ext.Ajax.abort(this.activeRequest[action]);
}
this.activeRequest[action] = Ext.Ajax.request(o);
}else{
this.conn.request(o);
}
// request is sent, nullify the connection url in preparation for the next request
this.conn.url = null;
}

});


With this Proxy, you can easily set up a restful store that PUTs and POSTS simple json to the webserver:




Ext.Ajax.defaultHeaders = {
'Accept': 'application/json'

};

// Create a non-standard HttpProxy instance.
var proxy = new Ext.ux.PureJsonHttpProxy({
url: '/webservices/users',
});



// The new DataWriter component.
var writer = new Ext.data.JsonWriter();

// Typical Store collecting the Proxy, Reader and Writer together.
var store = new Ext.data.Store({
id: 'userStore',
restful: true, // <-- This Store is RESTful
proxy: proxy,
reader: reader,
writer: writer, // <-- plug a DataWriter into the store just as you would a Reader
listeners: {
write : function(store, action, result, response, rs) {
App.setAlert(response.success, response.message);
}
}
});
I pretty much doubt that the modifications I made are done in the right place:-?.

Also the implementation is pretty static, because only the "data" object is read from the params. There is probably a better idea on how to do this. However i still post this, as I found some blog entries, who mentioned this problem, but I couldn't find any solution for it on the web or the forum.

Any comments on how to improve the code, or where to put that functionality will be appreciated...

christocracy
18 Aug 2009, 2:36 PM
Your extension Ext.ux.PureJsonHttpProxy should be unnecessary now. Just use the @cfg encode: false on Ext.data.JsonWriter. The HttpProxy will know what to do.



var writer = new Ext.data.JsonWriter({
encode: false
});


@see Ext.data.JsonWriter#render
@see Ext.data.HttpProxy#doRequest



/**
* @cfg {Boolean} encode <tt>true</tt> to {@link Ext.util.JSON#encode encode} the
* {@link Ext.data.DataWriter#toHash hashed data}. Defaults to <tt>true</tt>. When using
* {@link Ext.data.DirectProxy}, set this to <tt>false</tt> since Ext.Direct.JsonProvider will perform
* its own json-encoding. In addition, if you're using {@link Ext.data.HttpProxy}, setting to <tt>false</tt>
* will cause HttpProxy to transmit data using the <b>jsonData</b> configuration-params of {@link Ext.Ajax#request}
* instead of <b>params</b>. When using a {@link Ext.data.Store#restful} Store, some serverside frameworks are
* tuned to expect data through the jsonData mechanism. In those cases, one will want to set <b>encode: <tt>false</tt></b>, as in
* let the lower-level connection object (eg: Ext.Ajax) do the encoding.
*/
encode : true,