How to disable certain HTTP methods (like POST) for PersistedModel in LoopBack environment

When creating a model in the LoopBack environment, you can inherit from the PersistedModel class. All HTTP methods are generated this way. I am wondering how to disable some HTTP methods?

One option is to override functions from PersistedModel with empty logic, but wants the method to disappear from the Swagger API explorer.

+3


source to share


6 answers


Found the answer in the documentation. For example, this disables PersistedModel.deleteById:

var isStatic = true;
MyModel.disableRemoteMethod('deleteById', isStatic);

      

So it looks like you cannot disable all DELETE actions at the same time. For example, the persistedModel.deleteAll method remains available in this example.

The developer must disable each corresponding method from the PersistedModel class explicitly.



Relevant docs are here: http://docs.strongloop.com/display/public/LB/Exposing+models+over+REST

Sections:

  • Hiding Methods and REST Endpoints
  • Hiding endpoints for linked models
+1


source


I did below in the model.js files as shown below. This makes the table read-only.



module.exports = function(model) {

    var methodNames = ['create', 'upsert', 'deleteById','updateAll',
                      'updateAttributes','createChangeStream','replace','replaceById',
                      'upsertWithWhere','replaceOrCreate'
                     ];

    methodNames.forEach(function(methodName) {
        disableMethods(model,methodName)
    });
}


function disableMethods(model,methodName)
{
if(methodName!='updateAttributes')
model.disableRemoteMethod(methodName, true);
else
model.disableRemoteMethod(methodName, false); 
}

      

+3


source


The only thing that requires extra care is disabling methods on the user model (e.g. User.login). You need to call disableRemoteMethod before the explorer middleware: https://github.com/strongloop/loopback/issues/686

+1


source


I had the same problem.

My first solution was to manually update the items "public":true

in server/model-configuration.json

, but it was overridden anytime I used the Swagger tool to update the LoopBack API (using a command slc loopback:swagger myswaggerfilename

from the project root).

Finally, I wrote the Grunt problem as a robust solution.

  • Run it right after a generation slc loopback:swagger

    or just before running the realtime API.
  • you just need to provide the names of the paths I want to open in the javascript array list_of_REST_path_to_EXPOSE

  • and make sure you are happy with the backup folder for the original file /server/model-config.json

    .

I wanted to share it with you in case:

https://github.com/FranckVE/grunt-task-unexpose-rest-path-loopback-swagger

Basically:

module.exports = function (grunt) {

  grunt.registerTask('unexpose_rest_path_for_swagger_models_v1', function (key, value) {
    try {
      // Change the list below depending on your API project :
      // list of the REST paths to leave Exposed
      var list_of_REST_path_to_EXPOSE =
        [
          "swagger_example-api_v1",
          "write_here_the_paths_you_want_to_leave_exposed"
        ];

      // Location of a bakup folder for modified model-config.json (change this according to your specific needs):
      var backup_folder = "grunt-play-field/backups-model-config/";

      var src_folder = "server/";
      var dest_folder = "server/";
      var src_file_extension = ".json";
      var src_file_root_name = "model-config";

      var src_filename = src_file_root_name + src_file_extension;
      var dest_filename = src_file_root_name + src_file_extension;
      var src = src_folder + src_filename;
      var dest = dest_folder + dest_filename;
      var free_backup_file = "";

      if (!grunt.file.exists(src)) {
        grunt.log.error("file " + src + " not found");
        throw grunt.util.error("Source file 'model-config.json' does NOT exists in folder '" + src_folder + "'");
      }

      // timestamp for the backup file of model-config.json
      var dateFormat = require('dateformat');
      var now = new Date();
      var ts = dateFormat(now, "yyyy-mm-dd_hh-MM-ss");

      // backup model-config.json
      var root_file_backup = src_file_root_name + "_bkp" + "_";
      var root_backup = backup_folder + root_file_backup;
      free_backup_file = root_backup + ts + src_file_extension;
      if (!grunt.file.exists(root_file_backup + "*.*", backup_folder)) {
        //var original_file = grunt.file.read(src);
        grunt.file.write(free_backup_file, "// backup of " + src + " as of " + ts + "\n");
        //grunt.file.write(free_backup_file, original_file);
        grunt.log.write("Creating BACKUP"['green'] + " of '" + src + "' " + "to file : "['green'] + free_backup_file + " ").ok();
      } else {
        grunt.log.write("NO BACKUP created"['red'] + " of '" + src + "' " + "because file : " + free_backup_file + " ALREADY EXISTS ! "['red']).error();
        throw grunt.util.error("Destination backup file already exists");
      }

      // load model-config.json
      var project = grunt.file.readJSON(src);//get file as json object

      // make modifications in model-config.json
      for (var rest_path in project) {
        if (rest_path.charAt(0) === "_") {
          grunt.log.write("SKIPPING"['blue'] + " the JSON item '" + rest_path + "' belonging to the " + "SYSTEM"['blue'] + ". ").ok();
          continue; // skip first level items that are system-related
        }
        if (list_of_REST_path_to_EXPOSE.indexOf(rest_path) > -1) { //
          project[rest_path]["public"] = true;
          grunt.log.write("KEEPING"['green'] + " the REST path '" + rest_path + "' " + "EXPOSED"['green'] + ". ").ok();
        } else {
          project[rest_path]["public"] = false;
          grunt.log.writeln("HIDING"['yellow'] + " REST path '" + rest_path + "' : it will " + "NOT"['yellow'] + " be exposed.");
        }
      }

}

      

0


source


I wanted to hide the PATCH method, but when I tried to hide it I had to hide the PUT method, I used this line:

 Equipment.disableRemoteMethod('updateAttributes', false); 

      

but later I found a way to hide only the PATCH method, this line works fine for me.

 Equipment.sharedClass.find('updateAttributes', false).http = [{verb: 'put', path: '/'}];

      

The above line overrides the original http which has an updateAttributes method.

[{verb: 'put', path: '/'}, {verb: 'patch', path: '/'}]

0


source


Update on Santhosh Hirekerur's answer to hide everything on LB3, stop using the deprecated method Model.disableRemoteMethod

as well as the smarter way to hide updateAttributes

and any other future methods that might work the same.

I am checking if this method is in prototype and if it is, prefix the name prototype.

before disableRemoteMethodByName

:

module.exports = function (model) {

    var methodNames = [
        'create',
        'upsert',
        'deleteById',
        'updateAll',
        'updateAttributes',
        'patchAttributes',
        'createChangeStream',
        'findOne',
        'find',
        'findById',
        'count',
        'exists',
        'replace',
        'replaceById',
        'upsertWithWhere',
        'replaceOrCreate'
    ];

    methodNames.forEach(function (methodName) {
        if (!!model.prototype[methodName]) {
            model.disableRemoteMethodByName('prototype.' + methodName);
        } else {
            model.disableRemoteMethodByName(methodName);
        }
    });

}

      

I put the above code in server/middleware/disable-methods.js

and call it from a model like this:

var disableMethods = require('../../server/middleware/disable-methods');

module.exports = function (Model) {
    disableMethods(Model);
}

      

0


source







All Articles