Adding associated elements with Spring Data REST and Restangular - angularjs

I'm using Spring data REST named methods for my REST API. Some of exposed resources look like this:
Courses entity:
localhost:8080/data/courses/
Modules entity:
localhost:8080/data/courseModules
Each course can have multiple modules so I also have this:
localhost:8080/data/courses/{courseId}/modules - list of modules that are associated with course.
If I want to add new module I can naturally do this in two steps:
First add new module (with POST to localhost:8080/data/courseModules)
Associate newly added module with course (another POST to localhost:8080/data/courses/{courseId}/modules)
Question is:
Is it possible to do it in one step? I'm using Restangular and the way it works would suggest that this should be possible. With Restangular I would do something like this:
Restangular.one('courses', {courseId}).all('modules').post(newModule);
where newModule is json object.
Restangular than issued POST request to address: localhost:8080/data/courses/{courseId}/modules
This doesn't work hovewer. I'm getting "204 No Content" and no new object is added to my database. I can add new module making POST to this address: localhost:8080/data/courseModules but it would be so much easier if I could just make this request to localhost:8080/data/courses/{courseId}/modules. I expected that Spring Data REST will accept my POST request to localhost:8080/data/courses/{courseId}/modules and than automatically do the following:
Add new module
Create association of new module with course of id {courseId}
Thanks in advance for any hints.

The answer to the question YES. Following will be an approach i would like to suggest to you.
Say you have a scenario were
Add new course and modules
Delete an existing module.
Approach for scenario 1:
Endpoint URL : localhost:8080/data/courses/ HTTP Method : POST
The request body will be a JSON/XML which will have something like:
Course name [Module1, Module 2.....]
Approach for scenario 2:
Endpoint URL : localhost:8080/data/courses//id HTTP Method : DELETE
The request will contain an id of the module that has to be deleted.
Hope this ansers your question. Please let me know if you have any more question

Related

When updating a model on a RESTful API, should there be an update endpoint per field? or one endpoint for the model?

For a RESTful API, consider a model schema as follows:
MyCoolObject {
field_a
field_b
field_c
}
Is it better to create one update endpoint to update one or many fields on the model (PUT)? Or create one endpoint per field that would only update that one field (PATCH)?
Heuristic: how do you GET the information from your API?
Typically if you get the information a single resource with all of the information included in its representation...
GET /my-cool-object
Then you should also edit that information using the same resource
PUT /my-cool-object
PATCH /my-cool-object
POST /my-cool-object
In cases where you get the information from multiple resources (presumably via links)
GET /my-cool-object
GET /my-cool-object/a
GET /my-cool-object/b
GET /my-cool-object/c
Then you would normally edit the information in its own resource
PUT /my-cool-object/a
PATCH /my-cool-object/a
POST /my-cool-object/a

how to make django post accept str rather than pk

I have relational DB and a file info to post in it.
DB provides 3 entities holding ForeignKey in some attributes.
Entities are:
File, WorkFile and WorkFileStage
My issue is, when I post info of specific file, I must post on those endpoints, but e.g. WorkFile holds attribute file = ForeignKey(File) - it's an id filed. Which makes me POST all the File data, then GET it for acquring IDs, then POST on WorkFile with those IDs.
THIS IS A LOT OF POSTINGGETINGITERATINGANDPROMISING (as my request are done with axios on react).
What I've tried, is for POST data construct object with just a file=file_name, then search it in the DB on the Django side and serialize.save(). But POST requires pk rather than str for foreignKeys.
With this though process I ended up with:
axios.post().then(axios.get().then(axios.post(then))))
Is there any easy/good practice way of doing it?
Django's POST view can accept whatever you want. As for querying your models via related model properties, check the official documentation: https://docs.djangoproject.com/en/3.1/topics/db/queries/#lookups-that-span-relationships
In your case it should be something like this:
def my_post_view(request, file_name):
try:
work_file = WorkFile.objects.get(file__name=file_name)
except WorkFile.DoesNotExist:
raise Http404
...
where file_name is passed as a part of your endpoint URL.

Use query string in URL or use multiple URL?

If I want to display many posts in my web application but every post have its own type and I want to display each type in single page so, What's the best method to do that? Is put all all posts in one url and use query string to filter the posts upon the type and display it in the page?
For example : axios.get('/posts?type =sport')
Or I have to put every single type in separate Url
For example: axios.get('/posts/sport')
Also one more question please?
use one reducer to manage every posts or create one reducer for each post type?
you can add a dynamic route to every new type.
Ex:
'/transaction' -> component-1
'/transaction/:type' -> component-any (multiple)
welcome to Stackoverflow!
I can imagine you have a web API of some sort serving a URL /posts. You want to consume that endpoint from your web application, and you are using axios to do that. I can assume you are using JSON to return that data. Correct me if I'm wrong.
Now that the basic information is "clear", what data you serve from the endpoint, and how it is requested from the client is up to you. Do you want to ask the server what types are there first, and then do one AJAX request per type? Ok. Do you want to serve all posts independent of their type? Ok. Do you want to accept POST data in your controller so you can filter the results before returning a response? Ok.
If you are looking for a more specific answer, you must give more details, or specify more. But I hope I could be of help.
Edit: complete answer.
If you want to filter the results, you have to send some additional data in your POST request, in this case, your post type. In axios, this could be done like this:
axios.post('https://example.com/posts', {
type: 'sports'
}).then((data) => {
console.log(data);
});
You can obviously get the "type" value from a select input, other variable, even the current router page. I don't know your exact setup, but you can always come back and ask ;)
THEN, in your API controller you have to get that POST parameter type, and use it to filter the results. Again, I don't know your exact setup, but for MySQL if would be a WHERE statement in your query, or similar.

SuiteCommerce Advanced - Show a custom record on the PDP

I am looking to create a feature whereby a User can download any available documents related to the item from a tab on the PDP.
So far I have created a custom record called Documentation (customrecord_documentation) containing the following fields:
Related item : custrecord_documentation_related_item
Type : custrecord_documentation_type
Document : custrecord_documentation_document
Description : custrecord_documentation_description
Related Item ID : custrecord_documentation_related_item_id
The functionality works fine on the backend of NetSuite where I can assign documents to an Inventory item. The stumbling block is trying to fetch the data to the front end of the SCA webstore.
Any help on the above would be much appreciated.
I've come at this a number of ways.
One way is to create a Suitelet that returns JSON of the document names and urls. The urls can be the real Netsuite urls or they can be the urls of your suitelet where you set up the suitelet to return the doc when accessed with action=doc&id=_docid_ query params.
Add a target <div id="relatedDocs"></div> to the item_details.tpl
In your ItemDetailsView's init_Plugins add
$.getJSON('app/site/hosting/scriptlet.nl...?action=availabledoc').
then(function(data){
var asHtml = format(data); //however you like
$("#relatedDocs").html(asHtml);
});
You can also go the whole module route. If you created a third party module DocsView then you would add DocsView as a child view to ItemDetailsView.
That's a little more involved so try the option above first to see if it fits your needs. The nice thing is you can just about ignore Backbone with this approach. You can make this a little more portable by using a service.ss instead of the suitelet. You can create your own ssp app for the function so you don't have to deal with SCAs url structure.
It's been a while, but you should be able to access the JSON data from within the related Backbone View class. From there, within the return context, output the value you're wanting to the PDP. Hopefully you're extending the original class and not overwriting / altering the core code :P.
The model associated with the PDP should hold all the JSON data you're looking for. Model.get('...') sort of syntax.
I'd recommend against Suitelets for this, as that's extra execution time, and is a bit slower.
I'm sure you know, but you need to set the documents to be available as public as well.
Hope this helps, thanks.

ExtJS CRUD operations on Grid Panel and Grails backend

I am an absolute novice and have been working and struggling with ExtJS ! I am supposed to get a list of user records and dipslay them on Ext grid Panel. I have an ExtJS frontend and Grails ( Groovy Controllers ) backend. I have referred to a few links like:
http://docs.sencha.com/extjs/4.0.7/#!/example/grid/row-editing.html
http://docs.sencha.com/extjs/4.0.7/#!/example/restful/restful.html
http://docs.sencha.com/extjs/4.0.7/#!/example/writer/writer.html
The api property ( or ) tag ( or )attribute ( I don't know what it is called ) helps me in getting the list of JSON objects to be displayed in the Grid. Also, when I select a row and click on Delete, the request is reaching the delete action in my controller. But my problems begins here: how do I make sure that:
1) the selected row is deleted from Database? How do I pass the identifier or something to controller so that it will delete the record?
2) When I add a row, how do I pass the field values to backend Controller?
Most of the code is same as given in the restful link above. For reference, this is my Datastore:
https://docs.google.com/document/d/1gQyLCt6xWXTm-OUgYu7hku47r5WcS0my5yPBSKj2B7I/edit?usp=sharing
If you use a Rest proxy, ExtJS will auto generate the urls for you, based on the url stub that you specify. So if your proxy is configured to point to something like: /api/users, the following urls would be generated for each of the 4 actions:
read: /api/users (GET)
create: /api/users (POST)
update: /api/users/SomeIDFromTheUpdatedRecord (PUT)
delete: /api/users/SomeIDFromTheDeletedRecord (DELETE)
As you can see, the end point for each request is precisely the same (api/users), but for PUT and DELETEs, the id of the affected record is included in the URL automatically.
And of course, with POST and PUT requests, you can add any additional params that you'd like to send through to the server, although this will be done automatically when you persist the model instance via the store's configured proxy.

Resources