Richiesta di filtro e risposte nello stack MEZZO RESTful

4

Ho un servizio RESTful molto semplice scritto usando lo stack MEAN (MongoDb, Express.js, Angular.js, Node.js) e utilizzando l'ODM Mongoose.

Product schema

var productSchema = new mongoose.Schema({
  name: {type: String, required: true, maxlength: 250},
  _prices: [{
    amount: {type: Number,required: true,min: 0.0},
    date: {type: Date, required: true, default: Date.now}
  }]
});

productSchema
.virtual('price')
.get(function () {
  var price = this._prices[this._prices.length - 1];
  return price !== undefined ? price.amount : undefined;
});

productSchema.methods.setPrice = function (amount) {
  this._prices.push({amount: amount});  
};

Lo scopo della matrice _prices e della proprietà virtuale price è che voglio salvare una traccia di controllo della cronologia dei prezzi.

Ho un'interfaccia RESTful per /products che supporta il solito GET , POST , PUT e DELETE .

Nel mio sistema, gli amministratori sono autorizzati a POST , PUT e DELETE , il che è ovvio, tuttavia il problema si pone per l'accesso anonimo. Gli utenti anonimi sono autorizzati solo a GET , ma la risposta GET non deve includere il campo _prices , in quanto solo gli amministratori possono visualizzare la cronologia.

As anonimo

{
  name: "Widget", 
  price: "5.99"
}

Come amministratore

{
  name: "Widget", 
  price: "5.99", 
  _prices: [
    {price: "7.25", date: "2015-02-28"}, 
    {price: "5.99", date: "2016-01-09"}
  ]
}

La maggior parte delle esercitazioni che ho letto sullo stack MEAN mostrano sempre la restituzione del modello di mangusta direttamente.

exports.getAll = function(request, response) {
  Product.find({}, '-_prices', function (err, products) {
    res.json(200, products);
  });
};

Questo è molto semplice da aggirare dal controller products , tuttavia, trovo che sia molto mal riposto dato che questa logica di filtraggio è nel controller e fragile in quanto se aggiungo nuovi campi al mio schema, devo torna al controller per assicurarti di non esporre i campi in futuro.

Ho anche domande sull'andare dall'altra parte, facendo la convalida della richiesta. Sembra che la maggior parte delle esercitazioni abbia accettato l'input dell'utente così com'è e che la convalida di Mangusta abbia esito negativo.

exports.post = function(request, response) {
  var product = new Product(request.body)

  product.save(function(error, product) {
    if (error) {
      return response.json(422, error);
    }

    response.send(201);
  });  
};

Essendo stato utilizzato per ASP.NET WebApi, le mie opinioni su questo sono leggermente distorte. Avrei probabilmente creato modelli di visualizzazione separati per la richiesta e diversi modelli di visualizzazione per la risposta (a seconda che io sia autenticato o meno), eseguo la convalida dell'input sul modello di visualizzazione richiesta e ho solo la validazione invariabile all'interno della mia entità. Tuttavia, voglio assicurarmi che stia facendo il modo stack MEAN.

Le mie domande sono le seguenti:

  1. Devo fare affidamento esclusivamente sulla convalida della mangusta per la convalida dell'input, o dovrei scrivere la mia prima che arrivi anche a mangusta?

  2. Per il filtro di output, dovrei creare un modulo di sicurezza / filtro che accetti un Product e restituisca un modello di visualizzazione in base al contesto dell'utente, a seconda che si tratti di un amministratore oppure no?

  3. Devo sovrascrivere il comportamento di toJSON (che è estensibile in mangusta, comunque) per fare il filtraggio?

  4. Devo creare un livello di astrazione tra i miei controller e mangusta?

Il mio pensiero iniziale è che la stessa mangusta ha troppe responsabilità, ma non voglio evitare di usarla se è l'approccio migliore.

    
posta Matthew 10.01.2016 - 04:28
fonte

1 risposta

1
  1. Should I rely solely on mongoose's validation for input validation, or should I write my own before it even gets to mongoose?

Penso che questo tipo di controlli debba essere eseguito dal tuo servizio, tra i moduli DB e HTTP, non all'interno del DB.

  1. For output filtering, should I create a security / filtering module which accepts a Product and returns a view-model depending on the user's context, dependent on whether they're an administrator or not?

Non mi piace il modo in cui qualcosa viene restituito direttamente dal modello all'interfaccia HTTP, ma qui puoi semplicemente utilizzare il metodo più semplice: controlla i diritti nei gestori delle richieste e modifica l'oggetto rimuovendo campi aggiuntivi, se necessario. Questo richiederà meno linee.

  1. Should I override the toJSON behavior (which is extensible in mongoose, by the way) to do the filtering?

No.

  1. Should I create a layer of abstraction between my controllers and mongoose?

Intendi livello del modello di dati? No. Lascia che i tuoi controllori "controllino" questo.

    
risposta data 18.01.2016 - 12:54
fonte

Leggi altre domande sui tag