Suppose I have a complex object from html page which is mapped to this JSON structure:
{
id:"", //is not shown to user
title : "",
description: "",
summary: "",
// other too many fields
}
To update this record with "common" REST approach I should use:
- POST rest/record/{id}
With "common" approach entirely record object is marshalled to JSON object and is passed to REST service, then this entirely object is validated, passed to SQL query to data base and DB engine updates a record with all data. But what if user just update one symbol in the title?
In that case I should split this object into several:
{
id:"", //is not shown to user
{ recordId:"", title : "", } ,
{ recordId:"", description: "", } ,
{ recordId:"", summary: "", } ,
// other too many fields
}
How I should reorganize rest URLs? Like that:
- POST rest/record/{id}/title
- POST rest/record/{id}/description
- POST rest/record/{id}/summary
- others
Is this approach with URL good or bad (I mean both for javaScript from end and REST back end programming)? Is there any other approaches to handle this problem?
Instead of using POST, use PATCH and send only what's been changed:
PATCH rest/record/{id}
Data: { title: "new title" }
URLs such as rest/record/{id}/title, rest/record/{id}/summary, etc. aren't really RESTfull since they are not resources but properties of a resource.
See this past question for some exploration of options here (include PATCH).
Best practice for partial updates in a RESTful service
You have the following options:
use PATCH and send only the title
use PUT and send the whole data again
use PUT and use the property as a sub-resource with url: /resource/title
(POST is not idempotent, so you should not use that for update)
Related
my website relies on a database which is a big JSON file like this:
var myjsonData =
[ {
"ID": 0,
"name": "Henry",
"surname": "McLarry",
"...": "...",
}]
I do generate this data every month at high cost to me, therefore I would like to avoid calling it straight in my html <head>, because this will allow any user to download the full database in no time.
I would like to build a "something" that can only call specific items from the json file (just the only one I want to show) without "exposing" the full .json onto client side.
today I use the call
var myvar= myjsonData.ID.Name
to get "Henry" into myvar, I would like to build something like
var myvar = mycallfunction(ID,Name)
I did try with PHP as intermediary but the ajax calls from javacript doesn't allow me to fetch the data.
Can I use JQuery with the JSON Url to get only the item I need?
What you can do is parse your json for an object. So you can get any value you want from json.
Example:
var myjsonData = '{"ID": 0,"name": "Henry","surname": "McLarry"}';
obj = JSON.parse(myjsonData);
console.log(myjsonData.ID); //print the id
console.log(myjsonData.name); //print the name
console.log(myjsonData.surname); //print the surname
So you have a NoSQL Database which has only one kind of Document that is the full JSON element you use in your website. In that scenario you have three options:
Depending on the NoSQL Database you're using you can limit the fields which will be returned(I.e: For MongoDB you can look here: https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/)
Change the way you store you data into more modular documents and make the logic to connect them in you application. So instead of one big document you'll have modular ones as Users, Products, Transactions and etc and you can use your application to query them individually.
Build a Server Side logic as an API to deal with your data and provide only what you need, so the API(Which can be node.js, php, or any you may like) will get the full JSON it`s endpoints will only the data you want. For example: myapi.com/getUser, myapi.com/getProducts and so on.
If you're able to provide more info on the technologies you're using that would help us. Hope that helped :).
I have been traversing through Stackoverflow and everywhere else on the web to try and find a solution to my issue..
I am working in Javascript and attempting to POST a small section of JSON to an endpoint in the API i know is working (I have completes the GET and POST manually in Postman)
Here is my issue..
I want dont really want to do the "GET" in my programme I just want to either reference the file or even just store it in a little variable.
So for example I have in my code:
var OauthUpload = {
"objects": [
{
"name": "api",
"serviceID": 16,
"properties": {}
}
],
"version": "integration",
"environment": "redshift"
}
Then I am trying to reference this in the JS function:
function ApiPostOauth (port) {
$.post(OauthUpload, "http://docker.dc.test.com:" + getActualPort(port) + "/rest/v1/oauth/import", runner);
}
But I am having no joy! I have seen a few different silutions but none seem to fit for me.
Basically I want a way to just:
Reference my own JSON as a variable and then insert tht so my function "ApiPostOauth" has that inserted before it runs?
Thanks guys
Steve
I have put together an example for your use. When executing this code, the server will return the same object it is sent. So the 'OauthUpload` object is sent as the request body and the server returns the exact same object. Note: if you don't see output in the output panel when running the sample I will need to restart the server (leave a comment). This is here to demonstrate:
[EDIT] - after re-reading your question, it appears you would like to pass the 'OauthUpload` object into the function. I've updated the example.
You have a mistake in your call to jQuery post() method. As shown in the comments, the first two arguments are reversed in the call to post().
Since you didn't pick up on that, I decided to provide an example using your code. Since I don't have your server, I stood up a server for this example. So the URL and port will be different, but the AJAX call will be the same.
Please pay close attention to the OauthUpload object. Notice the property names are no longer surrounded by ". I removed these quotes because they seemed to be causing you confusion about JavaScript objects and JSON strings (there is no such thing as a JSON Object regardless of what you read on the web - JSON is a string format).
Next, look at the differences between the call made to $.post() in my example and your code. You will see the URL comes first in that call.
let url = "//SimpleCORSEnabledServer--randycasburn.repl.co/rest/v1/oauth/import";
let OauthUpload = {
objects: [{
name: "api",
serviceID: 16,
properties: {}
}],
version: "integration",
environment: "redshift"
}
ApiPostOauth(OauthUpload);
function ApiPostOauth(data) {
$.post(url, data, runner)
}
function runner(data) {
document.querySelector('pre').textContent = JSON.stringify(data, null, 2);
}
<pre></pre>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am currently using SAPUI5/OpenUI5 to consume and modify OData Services.
I want to create a new product entry over an HTTP POST Request and have problems to properly config the associations to a category. For developing reasons I am using a reference OData Service with this metadata. The Product already has the NavigationProperty to the right Category EntrySet.
<NavigationProperty Name="Category" Relationship="ODataDemo.Product_Category_Category_Products" FromRole="Product_Category" ToRole="Category_Products"/>
I am using the following JavaScript code in my controller:
var oCategory = oModel.getData("/Categories(0)");
var oEntry = {};
oEntry.ID = "10";
oEntry.Name = "Beer";
oEntry.Category = oCategory;
oModel.create("/Products", oEntry, {
method: "POST",
success: function(data) {...},
error: function(response) {...}
});
The product is successfully created /Products(10) but the relation to the existing category /Products(10)/Category is not working properly. Instead a new category with the same ID and information is created (is this meant with 'deep insert'?) but I want to use the elected category (of course).
Do I have to reference the category differently or can I create the associations manually somehow? Shouldn't the OData Service check if the category ID already exists and then use the existing entry?
Is there any best practices for such cases?
It's important to note that you are using an OData V2 service. Yes, by building the request the way you are doing it, you are actually doing a deep insert.
If you think about it, it makes sense, because you would not need to send the whole category information to just link the new product to the exiting category. What if you would change something in the category data? Should a deep insert result in an update?
In any case, OData v2 has something called "links" (see the OData terminology - www.odata.org). Basically each "association" between entities is represented through such a link. You can manage these links separately from the entity (e.g. you can remove and create links between existing entities; without having to change the entity itself - see the OData v2 operations, chapters 2.9 to 2.12).
Depending on the data format that you are using (by default, JSON if you are using sap.ui.model.odata.v2.ODataModel), you can create entity links in the same time when creating new entities. Check out this answer: https://stackoverflow.com/a/4695387/7612556.
In a nutshell, you would have to write something along the lines of:
oModel.create("/Products", {
ID: "10",
Name: "Beer",
Category: {__metadata: {uri: "/Categories(0)"}}
}, {
method: "POST",
success: function(data) {...},
error: function(response) {...}
});
I've tested my REST service with success using Advanced Rest Client, where I'm sending a payload that looks like this:
{
"comments":"test comments",
"internal_verification_areas":[
{
"area_id":"1",
"selected":"1",
"notes":"notes1",
"status":"1"
},
{
"area_id":"2",
"selected":"0",
"notes":"notes2",
"status":"0"
}]
}
As mentioned my REST function executes with success.
I then moved to implement the whole thing on my web-interface and created the internal_verification_areas object as follows:
var verification_areas = {
internal_verification_areas: [
{
area_id:"1", // no need to quote variable names
selected:"1",
notes:"noter",
status:"1"
},
{
area_id:"2", // no need to quote variable names
selected:"1",
notes:"noter2",
status:"1"
}
]
};
The whole thing is then fed into my request like this (comments parameter is fetched from a textarea):
$.post("createInternalVerification.php",{comments: $('textarea#korrigeringer').val(),internal_verification_areas: verification_areas}
createInternalVerification.php will json encode the data and request the service.
The problem is, that i get an error saying: "Integrity constraint violation: 1048 Column 'area_id' cannot be null". I assume there is something wrong with my posted data, but i can't figure out what. From my POV my Advanced Rest Client payload looks similar to the payload i send from my web-interface.
EDIT:
I've noticed that the network tab (google chrome) shows some differences in my payload. I'm returning internal_verification_areas in my response to analyze the difference.
(MY WEB INTERFACE RECEIVES)
{"error":false,"message":"Intern efterprovning oprettet","test":{"internal_verification_areas":[{"area_id":"1","selected":"1","notes":"noter","status":"1"},{"area_id":"2","selected":"1","notes":"noter2","status":"1"},{"area_id":"3","selected":"1","notes":"noter3","status":"1"}]}}
(ADVANCED REST CLIENT RECEIVES)
{"error":false,"message":"Intern efterprovning oprettet","test":[{"area_id":"1","selected":"1","notes":"jAAAAAAA","status":"1","id":"4"},{"area_id":"2","selected":"0","notes":"NEEEEEJ","status":"0","id":"5"}]}
Guess I messed up my understanding of objects and arrays. Turns out my web-interface was sending and array with and object with arrays. Changing it (as shown after this post) fixed my mistake. I'm so sorry zerkms for wasting your precious time and causing an immense annoyance to your unicum skilled mind. I find it more and more frightening to post questions on StackOverflow with the presence of such skilled and godlike figures who constantly remind minions such as myself that Stackoverflow has become the very bedrock of arrogant developers.
var internal_verification_areas = [
{
area_id:"1", // no need to quote variable names
selected:"1",
notes:"noter",
status:"1"
},
{
area_id:"2", // no need to quote variable names
selected:"1",
notes:"noter2",
status:"1"
},
{
area_id:"3", // no need to quote variable names
selected:"1",
notes:"noter3",
status:"1"
}
];
I'm trying to make a post but below does not appear to work it does not post but console.log() looks like a put request i.e
http://127.0.0.1/api/v1/participant?account=%7B%22pk%22:1%7D&email=someemail#gmail.com
factory
app.factory('CbgenRestangular', function(Restangular) {
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('http://127.0.0.1');
});
});
controller
$scope.participant = {email :$scope.email, password: "", account:{pk:1}};
CbgenRestangular.all('api/v1/participant').post("participant", $scope.participant);
What I'm I doing wrong?
according to the documentation (https://github.com/mgonto/restangular#lets-code):
// First way of creating a Restangular object. Just saying the base URL
var baseAccounts = Restangular.all('accounts');
var newAccount = {name: "Gonto's account"};
// POST /accounts
baseAccounts.post(newAccount);
note that post has a single input
you can add 'api/v1' to your base address - there's no need to carry it around (https://github.com/mgonto/restangular#setbaseurl)
I would also suggest using the plural form for a resource route, but that's a convention that some people don't follow - I guess it is a matter of taste