In Extjs5, erase() can't relate to destory api when the proxy type is rest - rest

This is my viewController:
onRestDeleteClick: function(){
var ouType = Ext.create('MyApp.model.OuType',
{
id: 49,
ouTypeName: 'Lenlee',
entityName: 'Lenlee'
});
ouType.erase();
}
The model whose id is 49 exists in database.
This is the OuType model:
Ext.define('MyApp.model.OuType', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name:'id'
},
{
name: 'ouTypeName'
},
{
name: 'entityName'
}
],
proxy:{
type: 'rest',
api: {
read: 'role/read',
update: 'role/update',
create: 'role/create',
destory: 'role/destory'
}
}
});
This is my server class:
#RequestMapping("/role")
#Controller("sysRoleContro")
public class SysRoleController {
…………
…………
#RequestMapping(value="/destory/{id}")
public void destoryOuType(HttpServletRequest request,
HttpServletResponse response, #PathVariable("id") Long id){
log.info("destory");
ouTypeRepository.delete(id);
log.info("end");
}
………
……
}
Now when i click the delete button, the request url is: http://localhost:7080/MyApp.model.OuType/49 404 Not Found.
The expected url is http://localhost:7080/CSQMS/role/destory/49
How can i delete the model?

Rest proxy is special in that that it does not CRUD operations to urls, as you set in api, but to HTTP verbs: GET, POST, PUT, DELETE, etc. So api config is most likely ignored. Configure the proxy this way:
proxy:{
type:'rest',
url:'/CSQMS/role'
}
If your server expects that CRUD operation verb is part of the URL you probably need a different proxy or you need to implement buildUrl method.

I want to say i'm so careless, i should write 'destroy' instead of 'destory'. MY GOD.

Related

Use DataFields in Rest URL in ExtJS to access Context.io API

I have two Question Regarding Rest API in EXTJS.
How can I use fields to make rest URL dynamic?
How can I add authentication key to access Context.io in my Rest.Proxy?
This is my solution, but I am not sure if I have done it properly, or not. I am pretty new in ExtJS, so my question may be basic, but I appreciate your help.
Ext.define("EmailFolders", {
extend: "Ext.data.Model",
fields: ["id", "label"],
proxy: {
type: "rest",
url: "lite/users/:" + id + "/email_accounts/:" + label + "/folders"
},
reader: {
type: "json"
},
headers: {
CONSUMER_KEY: "KEY FROM CONTEX.IO",
CONSUMER_SECRET: "SECRET FROM CONTEXT.IO"
}
});
You could use store.getProxy() to make rest URL dynamic and to pass the authentication keys in headers. Proxy have methods
proxy.setUrl() to sets the value of url.
proxy.setHeaders() to sets the value of headers.
You can check here with working fiddle
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
let url = 'https://jsonplaceholder.typicode.com/users';
// Set up a model to use in our Store
Ext.define('User', {
extend: 'Ext.data.Model',
proxy: {
type: 'ajax',
reader: {
type: 'json',
rootProperty: ''
}
}
});
Ext.define('MyStore', {
extend: 'Ext.data.Store',
model: 'User',
listeners: {
beforeload: function (store) {
var proxy = store.getProxy();
//if you want, you can also set here url inside of beforeload
//proxy.setUrl(url);
/*
* You can use {proxy.setHeaders} to set the values from CONTEX.IO
* After ajax request see your request parameter in network analysis below 2 headers are passed in request header
*/
proxy.setHeaders({
CONSUMER_KEY: "KEY FROM CONTEX.IO",
CONSUMER_SECRET: "SECRET FROM CONTEXT.IO"
});
}
}
});
let store = new MyStore();
//Set the dynamic url here
//This {url} will be dynamic whatever you want to pass
store.getProxy().setUrl(url);
store.load(function (data) {
console.log(data);
alert('Open console to see reposne..!')
});
/*
You can also pass url inside of load funtion
*/
new MyStore().load({
url: url + '/' + 1,
callback: function (data) {
console.log(data);
}
});
}
});

how can i protect REST Webservice from being hit if used from any tool

I am using Jersey REST Webservices for my Application which is responsible to show some data present in Database .
The website has got no user registration , so anybody can type the url and see the website .
My worry is that people can see the REST API calls from browser network tab and fire them .
My web service looks somewhat this way
package com.services;
#Path("/sgxservice")
public class SGXService {
#GET
#Produces("text/plain")
public String fetchsgxvalue() {
return "somevalue";
}
}
And this is the way i am making call to the webservice
function displaynewsbycompany(enteredtext) {
var url = 'http://localhost:8080/TradeOnlineChat/rest';
var s = "";
url = url + '/sgxservice,
jQuery.ajax({
type: 'GET',
url: url,
cache: false,
dataType: 'jsonp',
jsonp: false,
cache: false,
timeout: 17000,
async: false,
jsonpCallback: 'companynews',
success: function(newsbycompanyresponse) {
jQuery("#newsbycompanyRss").html("<ul class='feedEkList'>" + s + "</ul>");
},
error: function(x, t, m) {
jQuery(".loadingWrapforlivenews").hide();
}
})
.done(function() {
});
}
}
how can i protect REST Webservice from being hit if used from any tool

How to serve 404's using AngularJS and a RESTful API

Let's say you have an AngularJS application hooked up to a RESTful API and you have a route for "/item/:itemId".
.when('/item/:itemId', {
templateUrl: '/static/partials/item-detail.html',
controller: ItemDetailController
})
angular.module('angServices', ['ngResource']).factory('Item', function($resource) {
return $resource('/api/item/:itemId', {}, {
query: { method: 'GET', params: { itemId: '' }, isArray: true }
});
});
If the user goes to "/item/9" and an object with the itemId 9 does not exist, Angular will receive a 404 from the API, but will not naturally return a 404 to the user.
In other questions, I've seen people suggest creating an interceptor and having Angular redirect to a 404 error page when a resource is not found.
var interceptor = ['$rootScope', '$q', function(scope, $q) {
...
function error(response) {
if (response.status == 404) { window.location = '/404'; }
...
$httpProvider.responseInterceptors.push(interceptor);
However, I want to return a correct 404 with the original requested URL for SEO purposes.
Also, the solution above first loads the page and then redirects (just like Twitter used to do), so its sub-optimal.
Should I check server-side to first see if the resource exists before passing the request on to the Angular app? The downside of this is that it wouldn't work for broken links within the application.
What is the best way to approach this?
Maybe this jsfiddle can help you.
http://jsfiddle.net/roadprophet/VwS2t/
angular.module('dgService', ['ngResource']).factory("DriveGroup", function ($resource) {
return $resource(
'/', {}, {
update: {
method: 'PUT'
},
fetch: {
method: 'GET',
// This is what I tried.
interceptor: {
response: function (data) {
console.log('response in interceptor', data);
},
responseError: function (data) {
console.log('error in interceptor', data);
}
},
isArray: false
}
}
);
});
var app = angular.module('myApp', ['ngResource', 'dgService']);
app.controller('MainController', ['$scope', 'DriveGroup', function ($scope, svc) {
$scope.title = 'Interceptors Test';
svc.fetch(function (data) {
console.log('SUCCESS');
}, function () {
console.log('FAILURE');
});
}]);
I tried with this and works fine. I only change the fetch method to get.
In your case, you will need to change the console.log('FALIURE'); to $location.path('/404');.
GL!

RESTful Model, get rid of the id query param in the GET request

I'm a little bit stuck here. My model code is
Ext.define('MyFancyModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' }
],
proxy: {
type: 'rest',
url: '/fancymodel',
noCache: false
}
});
When I try to load data by id using
Ext.ModelManager.getModel('MyFancyModel').load('some-id', {});
the request url is /fancymodel/some-id?id=some-id which is obviously not correct. So how can I achieve the right request url: /fancymodel/some-id without any patches or overrides?
EDIT:
jsfiddle
In the developer console you can see failed GET request
http://fiddle.jshell.net/fancymodel/some-id?id=some-id
EDIT:
Thread on the Sencha forum
I haven't found any ExtJS solution, so I have written a small patch (not sure it works in every situations) :
Ext.override(Ext.data.proxy.Rest, {
buildUrl: function (request) {
delete request.params.id;
return this.callParent(arguments);
}
});
The standard way :
Ext.define('MyPatches.data.proxy.Rest', {
override: 'Ext.data.proxy.Rest',
buildUrl: function (request) {
delete request.params.id;
return this.callParent(arguments);
}
});

Custom proxies on Stores and Models seems inconsistent (and does not work on Models)

Am using Extjs 4, and have created a custom Rest Proxy to handle communication with my Zend backend api.
(See post http://techfrere.blogspot.com/2011/08/linking-extjs4-to-zend-using-rest.html)
When using a Store to handle communication, I was using Ext.require to load the proxy, and then referenced the proxy on the type field and all was good and it loaded my data: as per:
Ext.require('App.utils.ZendRest');
...
proxy : {
type : 'zest', // My custom proxy alias
url : '/admin/user'
...
}
I then decided to try to use the proxy directly on a model... and no luck. The above logic does not work.
Problems
1. When referencing zest, it does not find the previously loaded ZendRest class (aliased to proxy.zest)
2. It tries to load the missing class from App.proxy.zest (which did not exist.)
So I tried moving my class to this location and renaming to what it seemed to want. No luck.
It loads the class, but still does not initialize the app... I get no errors anywhere so v difficult to figure out where the problem is after this...
For now it seems I will have to revert to using my Zend Rest proxy always via the Store.
Question is... has anyone else seen the behavior? Is it a bug, or am I missing something?
Thanks...
Using your proxy definition, I've managed to make it work.
I am not sure why it doesn't work for you. I have only moved ZendRest to Prj.proxy namespace and added requires: ['Prj.proxy.ZendRest'] to the model.
Code:
// controller/Primary.js
Ext.define('Prj.controller.Primary', {
extend: 'Ext.app.Controller',
stores: ['Articles'],
models: ['Article'],
views: ['article.Grid']
});
// model/Article.js
Ext.define('Prj.model.Article', {
extend: 'Ext.data.Model',
fields: [
'title', 'author', {
name: 'pubDate',
type: 'date'
}, 'link', 'description', 'content'
],
requires: ['Prj.proxy.ZendRest'],
proxy: {
type: 'zest',
url: 'feed-proxy.php'
}
});
// store/Articles.js
Ext.define('Prj.store.Articles', {
extend: 'Ext.data.Store',
autoLoad: true,
model: 'Prj.model.Article'
});
// proxy/ZendRest.js
Ext.define('Prj.proxy.ZendRest', {
extend: 'Ext.data.proxy.Ajax',
alias : 'proxy.zest',
appendId: true,
batchActions: false,
buildUrl: function(request) {
var me = this,
operation = request.operation,
records = operation.records || [],
record = records[0],
format = me.format,
reqParams = request.params,
url = me.getUrl(request),
id = record ? record.getId() : operation.id;
if (me.appendId && id) {
if (!url.match(/\/$/)) {
url += '/';
}
url += 'id/' + id;
}
if (format) {
reqParams['format'] = format;
}
/* <for example purpose> */
//request.url = url;
/* </for example purpose> */
return me.callParent(arguments);
}
}, function() {
Ext.apply(this.prototype, {
actionMethods: {
create : 'POST',
read : 'GET',
update : 'PUT',
destroy: 'DELETE'
},
/* <for example purpose> */
reader: {
type: 'xml',
record: 'item'
}
/* </for example purpose> */
});
});
Here is working sample, and here zipped code.