Admin on rest - RestClient & Create operation return params + id instead of response.data - admin-on-rest

In the two REST client (simple & json) provided in the module, on the CREATE operation we have this :
case CREATE:
return { data: { ...params.data, id: json.id } };
params is the data sended by the client to the server, json is the data that the server returned.
Why is better to return client data than server response ?

In the two REST clients, we assume that we can't prejudge what the server will return to us, but the new element's id.
And we're assuming that the data provided for creation will allow the correct display of the list.
But of course, if this is not your case (i.e. you know exactly what the server will return, including some information not requested at creation), you can decorate an existing client or create your own.

Related

Creating Resolvers that work with an external FHIR Server

I am exploring this library
https://github.com/Asymmetrik/graphql-fhir
It does not contain logic for how to implement resolvers for a 3rd party FHIR Server.
Has anyone attempted this?
I'll add some pseudo code below, but that library is essentially a wrapper and has no backend, so you can definitely use it to wrap other FHIR servers. GraphQL resolvers can resolve sync or async. So if we took the patient resolver (https://github.com/Asymmetrik/graphql-fhir/blob/master/src/resources/4_0_0/profiles/patient/resolver.js), for example, and wanted to connect it to a third party server, like HAPI or some other server. You could implement it like so (pseudocode so untested):
module.exports.getPatient = function getPatient(root, args, context = {}, info) {
// args contains the arguments in GraphQL format, note that these may
// not map directly to another FHIR server for naming restriction reasons
// e.g. fooBar in graphql might be foo-bar in REST
// Make an HTTP request, use any http library, for example, fetch
return fetch('some/fhir/server/patient', {
method: 'post',
body: JSON.stringify(args) // remember args may need to be mapped
})
.then(response => response.json())
.then(results => {
// Make sure the response matches what the resolver expects, in this
// case, a single patient
return results;
});
};
There is an example at https://github.com/Asymmetrik/graphql-fhir/blob/master/FAQ.md#resolvers, but that is loading a local patient, you just need to make an HTTP request to some 3rd party server and return the results asynchronously. For handling errors, make sure to check out this as well, https://github.com/Asymmetrik/graphql-fhir/blob/master/FAQ.md#resolvers.

How to customize the CRUD response toaster message [admin-on-rest]

I want to add server response message in CRUD response toaster. For Example when we do an update, we will get 'Element updated' toaster message. Instead of it I want to show some dynamic (not static) server responded message.
This is only supported for error messages currently. If this is really important, please open a feature request and we'll consider it.
A slightly long winded way to do this. But definitely possible.
1) Write a custom restWrapper or RestClient
https://marmelab.com/admin-on-rest/RestClients.html
2) Handle the request and response from it like below.
function handleRequestAndResponse(url, options={}, showAlert={}) {
return fetchUtils.fetchJson(url, options)
.then((response) => {
const {headers, json} = response;
//admin on rest needs the {data} key
const data = {data: json}
if (headers.get('x-total-count')) {
data.total = parseInt(headers.get('x-total-count').split('/').pop(), 10)
}
// handle get_list responses
if (!isNaN(parseInt(headers.get('x-total-count'), 10))) {
return {data: json,
total: parseInt(headers.get('x-total-count').split('/').pop(), 10)}
} else {
return data
}
})
}
3) you now have a place in your code where you can intercept the data from the server. In above code you can define and shoot actions containing your data whenever you need. Create a reducer that takes the data from your action and populates a field in the state you can call it notification.
4) Use the redux-saga select method
How to get something from the state / store inside a redux-saga function?
You can now access the notification data from the store and show custom toaster messages to your heart's content :)

Parse Cloud Code on Heroku User Query

I am trying to access properties located on the User object for the current user in a cloud code function. The current user is passed to the cloud code function and available at request.user. The Cloud Code is deployed to Heroku using parse-cloud-express.
When the request first arrives, it does not contain the user data other than the id.
So I tried performing a fetch to get the latest data:
Parse.Cloud.define("functionName", function (request, response) {
request.user.fetch().then(function (user) {
console.log(util.inspect(user));
});
});
But it outputs the same data and does not seem to include the User object's properties.
2015-12-15T01:19:08.830880+00:00 app[web.1]: { _objCount: 1, className: '_User', id: 'dKqZMSRgDc' }
I also tried performing a query on the user id, but receive the same result.
var userQuery = new Parse.Query(Parse.User);
userQuery.get(request.user.id).then(function (user) {
console.log(util.inspect(user));
});
How do I get the properties of the User object?
The problem was not with getting data for the User object, but the way I was logging it. It seems that the data is not available from the object itself, so the output from util.inspect was correct, but does not include any properties. (I'm guessing the internals of the Parse framework manages this in another way.)
I replaced with console.log(user.toJSON()) and can now see the expected data for the user.

Ember Data update POST when it should be PUT

I'm working on an Ember.js app. I have an update function, part of an ObjectController.
The function should save my updated model, however when I call save(); it sends a POST request not a PUT request. (Tested in Chrome.)
Why would that happen? How can I make sure a PUT request is sent for updates?
Here is my code:
customer = this.get('model');
customer.set('name', 'New name');
customer.save();
For extra reference, when I log the "dirtyType" with console.log( customer.get('dirtyType') ); it says "updated".
Any help very much appreciated!
UPDATE
I've adjusted the sample code above to make it clearer, I am NOT creating a new model and wanting to use PUT. I have an existing model that I need to update.
I'm not sure if your workaround is correct in the land of PUT vs POST.
TL;DR PUT should define the resource (by Request-URI), but we don't do that during creation, so we shouldn't be using a POST. Override the create/save if you need this for your server, instead of hacking the isNew property, which may come back to bite you.
Put
9.6 PUT
The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. If the Request-URI refers to an already
existing resource, the enclosed entity SHOULD be considered as a
modified version of the one residing on the origin server. If the
Request-URI does not point to an existing resource, and that URI is
capable of being defined as a new resource by the requesting user
agent, the origin server can create the resource with that URI. If a
new resource is created, the origin server MUST inform the user agent
via the 201 (Created) response. If an existing resource is modified,
either the 200 (OK) or 204 (No Content) response codes SHOULD be sent
to indicate successful completion of the request. If the resource
could not be created or modified with the Request-URI, an appropriate
error response SHOULD be given that reflects the nature of the
problem. The recipient of the entity MUST NOT ignore any Content-*
(e.g. Content-Range) headers that it does not understand or implement
and MUST return a 501 (Not Implemented) response in such cases.
If the request passes through a cache and the Request-URI identifies
one or more currently cached entities, those entries SHOULD be
treated as stale. Responses to this method are not cacheable.
The fundamental difference between the POST and PUT requests is
reflected in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed
entity. That resource might be a data-accepting process, a gateway to
some other protocol, or a separate entity that accepts annotations.
In contrast, the URI in a PUT request identifies the entity enclosed
with the request -- the user agent knows what URI is intended and the
server MUST NOT attempt to apply the request to some other resource.
If the server desires that the request be applied to a different URI,
Custom Adapter
App.ApplicationAdapter = DS.RESTAdapter.extend({
createRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record, { includeId: true });
//return this.ajax(this.buildURL(type.typeKey), "POST", { data: data });
return this.ajax(this.buildURL(type.typeKey), "PUT", { data: data });
},
updateRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record);
var id = get(record, 'id');
// you could do the same here, but it's even more incorrect
return this.ajax(this.buildURL(type.typeKey, id), "PUT", { data: data });
},
});
http://www.ietf.org/rfc/rfc2616.txt
Thank you for all of your help guys, however I have found the issue and it is ridiculously silly.
The API I have been using had a new flag "is_new" and that had been added to the model and was overwriting the "isNew" property.
Causing Ember (and me) to get very confused.
I've tweaked the API and all is good in the world!
If the model was created with createRecord, and thus has isNew == true and you call save() the expected behavior is POST. Once the record has been persisted, and it is changed, and thus isDirty == true but isNew == false then the save() will be a PUT.
This is described in the Models Guide.

Ajax request, should it be POST or PUT

I have created a Spring MVC web app.
The app makes a few calls to the controller. These calls are close/open/end game.
I make these calls using Ajax, so I can handle a response on the top of the page.
ajaxPost = function (url, action, id, onSuccess, onError) {
$.ajax({
type: "POST",
url: url + "?" + action + "=" + id,
success: function(response) {
if(onSuccess !== null) {
onSuccess(response);
}
},
error: function(e) {
if(onError !== null) {
onError(e);
}
}
});
};
The question I have is that I'm using 'POST' for the Ajax request, is that correct, or should it be 'PUT'?
My controller has a default URL, and I'm using the param attribute to decide which method to call, as I have many buttons on the page.
#RequestMapping(params = "open", method = RequestMethod.POST)
#RequestMapping(params = "close", method = RequestMethod.POST)
It doesn't sit well with me that I'm using 'POST' for these calls. Maybe it should be 'PUT'...
Any suggestions? Does it matter?
It depends on what your request should do. So there's no general rule that you should use one over the other, they have different use cases.
POST for creating a record.
PUT for updating an existing record (or putting a record at a specified location/id).
See this wikipedia article for the definitions.
One thing to note is that PUT should be idempotent, doing the same PUT request multiple times should ideally produce the same result as doing a single PUT request. However, POST is not idempotent, so doing several POST requests should (or will) create multiple new records.
So after having read this you should check what your method does, and select the corresponding request method.
Both PUT and POST may create a new record; PUT may also update/change an existing record.
The difference between POST and PUT is that PUT is expected to address the record with it's ID, so that the server knows what ID to use when creating (or updating) the record, while POST expects the server to generate an ID for the record and return it to the client after the record has been created.
Thus, a POST is addressed to the resource as a collection: POST /resource, while PUT is addressed to a single item in the collection: PUT /resource/1
Use POST. Always use POST, unless you're absolutely rock-solid certain that PUT is properly supported by your hosting system.

Resources