最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to disable certain HTTP methods (e.g. POST) for PersistedModel in LoopBack framework - Stack Overflow

programmeradmin2浏览0评论

When you create model in LoopBack framework, you can inherit from PersistedModel class. This way all the HTTP methods are generated. I am wondering how can I disable certain HTTP methods?

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

When you create model in LoopBack framework, you can inherit from PersistedModel class. This way all the HTTP methods are generated. I am wondering how can I disable certain HTTP methods?

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

Share Improve this question asked Nov 16, 2014 at 17:23 luboskrnacluboskrnac 24.6k10 gold badges86 silver badges93 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 3

I did below in model.js files like below. This makes table readonly.

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); 
}

The only thing which requires additional care is disabling of custom model methods (like User.login). You need to call disableRemoteMethod before explorer middleware: https://github./strongloop/loopback/issues/686

An update on Santhosh Hirekerur answer to make it hide everything on LB3, stop using the deprecated Model.disableRemoteMethod method and also a more intelligent way to hide updateAttributes and any other future methods that may work the same.

I check to see if the method is on the prototype and if it is, prefix the name with prototype. before we 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 so:

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

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

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

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

So it looks like you it's not possible to disable all DELETE actions at the same time. For example method PersistedModel.deleteAll remains accessible in given example.

Developer must disable each relevant method from PersistedModel class explicitly.

Relevant docs are here

Sections:

  • Hiding methods and REST endpoints
  • Hiding endpoints for related models

In case of loopback 3

I had the same problem.

My first solution was to manually update the "public":true items in server/model-configuration.json but it was overridden anytime I used the Swagger tool to refresh the LoopBack API (with slc loopback:swagger myswaggerfilename mand from the project root).

I finally wrote a Grunt task as a reliable workaround.

  • Run it just after a slc loopback:swagger generation or just before running the API live.
  • you just have to specify the names of the paths I want to expose in the javascript array list_of_REST_path_to_EXPOSE
  • and make sure you are happy with the backup folder for the original /server/model-config.json file.

I wanted to share it with you in case:

https://github./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.");
        }
      }

}

I wanted to hide the PATCH method, but when I was trying to hide it also I got to hide the PUT method , I was using this line :

 Equipment.disableRemoteMethod('updateAttributes', false); 

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

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

The above line overrides the original http that updateAttributes method had.

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

发布评论

评论列表(0)

  1. 暂无评论