REST
REST (representational state Transfer) is a software design architecture style that defines a bunch of concepts that can effectively reduce business complexity with these abstract concepts and related rules. While the daily use of HTTP is the best practice of rest style, restful Web services is to use HTTP as an application layer protocol to comply with, rather than other (such as SOA) as the transport layer of the tool, and then on the HTTP build its own set of application layer protocol.
When we type the Url/uri in the browser address bar is the rest provided resource (Resource) definition, and the resource is a concept in rest (concepts), when the browser makes a request, it wants to get a specific representation of a concept ( Representation), our common Web page is the specific representation of the resource. The concepts and principles of rest are defined in order to minimize the coupling between the service and the application using the service. Our principle of designing RESTful Web services only follows some of the principles of rest. The picture comes from "talking about rest", as we can see in the rest triangle diagram that the URL is the so-called noun (the location of the resource), and some HTTP methods are verbs, and JSON, XML Data Formats act as a concrete representation of the resource.
The following is a brief overview of the 4 RESTful Web service fundamentals, excerpted from IBM's Rest-based Web Services Foundation
Explicitly using the HTTP methodWhen you design restful, you use 4 more polymorphic methods (POST, GET, PUT, DELETE) to implement CRUD operations for data storage. These verbs (POST, GET, PUT, and DELETE) have been defined by the HTTP protocol.
- The HTTP get method is used to get a resource, which does not change the state of the resource, and may result in different results, but it does not have side effects (that is, no modification to the data stored on the source server).
- The HTTP Delete method is used to delete resources although there are side effects, but the side effects of multiple invocations should be the same, that is, the deletion of the corresponding resource for the URI.
- The HTTP post method is used to accept the created resource, and if the resource is already created on the server, the server response should be the 201 state that represents created and the URI of the resource, avoiding the POST request creating multiple copies of the same resource on the server.
- The HTTP put method is used to create or update resources, and the side effects of multiple operations are the same as a put operation. The even if server does not have a put resource to create one, otherwise it can update existing resources.
The result of these actions is that there must be expectations, there should be no semantic problems, and the typical example is that only get is used in the application to act as a method of all front-end interaction, and the result is that the behavior of some web crawlers inadvertently leads to server-side resource changes.
No statusThe stateless state of the network transport makes each request independent and complete, allowing the request to be routed from one server to another without the state being reconciled. Of course the request is stateful, transferring most of the state maintenance responsibilities to the client application, which can save bandwidth and minimize server-side application state performance improvements.
Public directory-structured URIA URI is a tree of subordinate and ancestor branches that are joined together on a node, which can visually express the interaction type and resource name, or the URI as an interface to the document description.
The transport format uses data formats such as XML, JavaScript Object Notation (JSON), and so onThese data formats enable services to be run on different platforms and devices and written in different languages.
Code
We first design node to accept the routing assignment when the front-end request is received, temporarily providing only the following CRUD operations for a single Dtree object.
///store APIapp.post(‘/dtree‘, dtreeCtrl.createDTree);//createapp.get(‘/dtree/:dtree_id‘, dtreeCtrl.readDTree);//readapp.put(‘/dtree/:dtree_id‘, dtreeCtrl.updateDTree);//updateapp.delete(‘/dtree/:dtree_id‘, dtreeCtrl.deleteDTree); // delete
We exposed the processing request API at Dtreectrl, which is handled as follows for the post operation.
For get operations, we use DTREE_ID as _id for searching, calling the Mongoose API. Lean () Converts the result to plain JavaScript objects.
Execute route get/dtree/:d tree_idexports.readdtree =function(req, res) {var checkid =new ObjectId (req.params.dtree_id); //storage to MongoDB pre-processing //. Dtree.findbyid (Checkid). Lean (). EXEC (function (err, dtree) {if (err) {Console.log ( "Error: Readdtree:db failed to FindByID due to ', err); Res.send ({ ' success ': false, ' err ' : Err}); }else{console.log ( ' Info:readDTree:DB FindByID successfully Dtree = ', dtree); //sent to the client for preprocessing //... res.send ({true, dtree:dtree}); } });};
For the put operation, I previously wrote V for Versionkey, which can act as the version control flag for a database document, but the Mongoose. Update () method has some bugs, and the value of V is not modified after the operation, and the temporary workaround is through $inc: {key: Value} to set manually.
Execute route put/dtree/:d tree_idexports.updatedtree =function (req, res) {// Pre-storage to MongoDB //: Dtree.update ({ "_id": id}, {modifiedkey:modifieddata, $inc: { __v: 1}}, functionif (err) {Console.log ( "Error:updatedtree : DB failed to update due to ', err); Res.send ({ ' success ': false, ' err ' : Err}); }else{console.log ( ' Info:updateDTree:DB Updated successully Dtree '); Res.send ({ ' success ': true});});};
The
Delete operation is relatively straightforward.
//execute Route delete/dtree/:d tree_ Idexports.deletedtree = function (req, res) {Dtree.findbyidandremove (req.params.dtree_id, < Span class= "Hljs-keyword" >function (err, dropdtree) {if (err) { Console.log ( ' Error:deleteDTree:DB failed to delete due to ', err); Res.send ({ success ': false, ' err ': err}); }else{console.log ( ' Info:deleteDTree:DB deleted successfully Dtree = ', dropdtree); Res.send ({ ' success ': true});}});
At this point, the backend has been established with a set of restful APIs to provide to client HTTP request calls. We first need to use the previously mentioned $resource service definition decision tree CRUD Operations Service Dtreecrudservice, where the URI uses the cors notation, in fact, there is no need to use/dtree/alone:d tree_id can also, This is the resource that accesses this machine. CORS (cross origin Resource sharing) is in contrast to the SOP (same Origin Policy, which refers to a document or script that can only access the server's own domain on the client, cannot get or modify the properties of the document of another domain), and it supports inter-domain requests. Nodejs opens cors through a call to Cors-dependent packages. If the browser side detects the appropriate settings, you can allow xhr for cross-domain access.
$resource(‘http://localhost\\:4000/dtree/:dtree_id‘, {},{ ‘get‘: { method:‘GET‘ }, update: { method: ‘PUT‘ //a PUT request }, ‘delete‘: { method:‘DELETE‘ }});
The method of HTTP operation is defined here, and the service can be invoked correctly by "injecting" the service into the controller.
app.controller(‘createDTreeCtrl‘, [ ‘$scope‘, ‘dtreeCrudService‘ function ( $scope, dtreeCrudService ) { //...具体实现]);
This is done by defining a crud method to divide the business logic.
Upload decision tree data to backend for database$scope. Createdtreedata =function(){Data after the front-end processingvar data = someoperate (data); Console.log (' Info:createDtreeData:data = ', data); Dtreecrudservice.save (data,function(RES) {if (res.success) {Console.log (' Info:createdtreedata:back-end successfully saved Dtree = ', data); }else{Console.log (' Error:createdtreedata:back-end failed to save Dtree due to ', res.err); } },function(Error) {Console.log ("Error:createDtreeData:Fail to create due to", Error);});Reading data$scope. Readdtreedata =function() {Dtreecrudservice.get ({dtree_id:' 54a4c0947752adcc1764f0d4 '},function(RES) {if (res.success) {Console.log ("Info:readdtreedata:back-end successfully read Dtree =", Res.dtree);}else{Console.log (' Error:readdtreedata:back-end failed to read dtree due to ', res.err); } },function(Error) {Console.log ("Error:readDtreeData:Fail to read due to", Error);});Update data$scope. Updatedtreedata =function() {The data is structured into JSON objects.var data = Somechange (data); Console.log (' Info:updateDtreeData:data = ', data); Dtreecrudservice.update ({dtree_id:data._id},data,function(RES) {if (res.success) {Console.log ("Info:updatedtreedata:back-end successfully update Dtree =", data);}else{Console.log (' Error:updatedtreedata:back-end failed to read dtree due to ', res.err); } },function(Error) {Console.log ("Error:updateDtreeData:Fail to update due to", Error);});//Delete the decision tree of an ID $scope. Deletedtreedata = function () { Dtreecrudservice.delete ({dtree_id: $scope. Operate_dtreeid}, function (res) {if (res.success) {console.log (" Info:deletedtreedata:back-end successfully Delete Dtree "); }else{console.log ( ' Error:updatedtreedata:back-end failed to Read Dtree due to ', res.err); }}, function (Error) { Console.log ( "Error:deleteDtreeData:Fail to delete due to", Error);});
These 4 methods correspond to the request, which can be called using the ng-click instruction.
The use of Ngresource's Crud method is so convenient that later modifications are especially handy.
$resource (URL, [paramdefaults], [Actions], options);
Referring again to the role of the Pramas parameter in this $resource method, the HTTP request method is overwritten when the parameter is not empty. For example $resource ("/dtree/:id", {ID: @dtreeID}, methods) This section of the resource service, our post data is {"DtreeID": 2333, "Dtreedata": YoYo }, this URL becomes/dtree/2333. And when there is no this @ symbol, the URL is a direct/dtree/dtree_id.
Another thing is that our back-and-forth data is in JSON format, and JSON does not support looping structure, i.e. A.B = C; C.D = b; This data structure, but in front of the use of D3 drawing process, it is necessary to maintain this structure in order to update the image on the interface in real time. If you forcibly use $resource to pass, JavaScript converts the data to a JSON object and then reports TypeError errors.
Then we need not panic, directly traverse the decision tree data to the loop structure to kill it.