Soru Düğüm / Express ile kurumsal uygulama oluşturma


Enterprise applciation ile Node / Express / Mongo (aslında MEAN yığınını kullanarak) nasıl yapılandırılacağını anlamaya çalışıyorum.

2 kitap ve bazı googling (benzer StackOverflow soruları dahil) okuduktan sonra, Express kullanarak büyük uygulamaları yapılandırmanın iyi bir örneğini bulamadım. Okuduğum tüm kaynaklar uygulamayı aşağıdaki varlıkları kullanarak bölmeyi önerir:

  • rotalar
  • kontrolörleri
  • modeller

Fakat bu yapı ile gördüğüm en büyük problem, denetleyicilerin tanrı nesnesi gibi olduğudur. req, res Doğrulamadan sorumlu nesneler iş mantığına sahip olmak dahil.

Diğer tarafta, yollar bana aşırı mühendislik gibi geliyor çünkü yaptıkları tek şey denetleyici yöntemlerine uç noktaları (yolları) eşliyor.

Scala / Java arkaplanım var, bu yüzden tüm mantığı 3 kademe - kontrolör / servis / dao olarak ayırma alışkanlığım var.

Benim için aşağıdaki ifadeler idealdir:

  • Kontrolörler sadece WEB kısmı ile etkileşim için sorumludur, yani marshalling / unmarshalling, bazı basit doğrulama (gerekli, min, max, email regex vb);

  • Hizmet katmanı (aslında NodeJS / Express uygulamalarında kaçırdım) yalnızca iş mantığı, bazı ticari doğrulamadan sorumludur. Hizmet katmanı WEB kısmı hakkında hiçbir şey bilmiyor (yani, yalnızca web içeriğinden değil, diğer uygulama alanlarından çağrılabilirler);

  • DAO katmanına gelince, benim için açık. Mongoose modelleri aslında DAO, bu yüzden bana burada en açık şey.

Gördüğüm örneklerin çok basit olduğunu ve sadece Düğüm / Ekspresyon kavramlarını gösterdiklerini, ancak iş mantığının / validasyonunun çoğunu içeren gerçek bir dünya örneğine bakmak istediğimi düşünüyorum.

DÜZENLE:

Başka bir şey bana açık değil, DTO nesneleri yok. Bu örneği düşünün:

const mongoose = require('mongoose');
const Article = mongoose.model('Article');
exports.create = function(req, res) {
    // Create a new article object
    const article = new Article(req.body);
    // saving article and other code
}

JSON nesnesi var req.body Mongo belgesi oluşturmak için parametre olarak geçirilir. Benim için kötü kokuyor. Ham JSON ile değil, somut sınıflarla çalışmak istiyorum

Teşekkürler.


32
2018-01-26 14:23


Menşei


Bu soruyu kontrol etmek isteyebilirsiniz: stackoverflow.com/questions/5178334/...   Ve bu düşünce: gist.github.com/lancejpollard/1398757 - rocketspacer
Uygun gördüğünüz şekilde yapılandırabilirsiniz. Doğrudan denetleyicinin altında bir makale oluşturmak yerine, onu farklı bir dizinin altındaki Service.createArticle adı altında başka bir katmana ayırabilir ve bunu (yalnızca java'da içe aktarma gibi) kullanım için kullanabilirsiniz. - rocketspacer
Req.body nesnesi hakkında, body-parser gibi ekspres-middleware kullandıysanız Javascript nesnesine dönüştürülmelidir. Ve evet artık ham JSON olmasa bile, hala doğrudan DTO yapıcısına aktarmıyoruz. Bazı doğrulama ve sanitizasyon geçmek zorunda - rocketspacer
Bir projenin yapılandırılmasında doğru ya da yanlış bir şey yoktur, farklı kurumsal projeler farklı yapılar yaratır çünkü farklı şeyler yaparlar. Bazılarının socket.io gibi gerçek zamanlı çerçeveyi desteklemesi gerekiyor, bazılarının mesaj kuyruklarını tüketmek için arka plan fonuna ihtiyaç duyması ve diğer şeylerin demetlenmesi gerekiyor. Uygulamanızı bildiğiniz şekilde yapılandırın, yapı yavaş yavaş uygulama ölçeğiniz olarak değişecektir - rocketspacer


Cevaplar:


Kontrolörler, onları istemedikçe Tanrı nesneleridir ...
- zurfyx demiyorsun (╯ ° □ °) ╯︵ ┻━┻

Sadece çözümle ilgileniyor musunuz?  Üzerine atla son bölüm "Sonuç".

┬──┬◡ ノ (° - ° ノ)

Cevabı almaya başlamadan önce, bu yanıtı normal SO uzunluğundan daha uzun sürdüğü için özür dilememe izin verin. Kontrolörler tek başına hiçbir şey yapmazlar, hepsi MVC modeliyle ilgilidir. Bu yüzden, asgari sorumlulukları olan uygun yalıtılmış denetleyicilere nasıl ulaşacağınızı göstermek için Yönlendirici <-> Denetleyici <-> Hizmet <-> Modeli ile ilgili tüm önemli ayrıntıları incelemekle alakalı olduğunu düşündüm.

Varsayımsal durum

Küçük bir varsayımla başlayalım:

  • AJAX aracılığıyla bir kullanıcı aramasına hizmet veren bir API'ye sahip olmak istiyorum.
  • Socket.io aracılığıyla aynı kullanıcı aramasına da hizmet veren bir API'ye sahip olmak istiyorum.

Express ile başlayalım. Bu kolay, peasy değil mi?

routes.js

import * as userControllers from 'controllers/users';
router.get('/users/:username', userControllers.getUser);

kontrolörleri / user.js

import User from '../models/User';
function getUser(req, res, next) {
  const username = req.params.username;
  if (username === '') {
    return res.status(500).json({ error: 'Username can\'t be blank' });
  }
  try {
    const user = await User.find({ username }).exec();
    return res.status(200).json(user);
  } catch (error) {
    return res.status(500).json(error);
  }
}

Şimdi Socket.io parçasını yapalım:

Çünkü bu bir socket.io soru, ben kalıbı atlayacağım.

import User from '../models/User';
socket.on('RequestUser', (data, ack) => {
  const username = data.username;
  if (username === '') {
    ack ({ error: 'Username can\'t be blank' });
  }
  try {
    const user = User.find({ username }).exec();
    return ack(user);
  } catch (error) {
    return ack(error);
  }
});

Uhm, burada bir şeyler kokuyor ...

  • if (username === ''). Kontrol validatorunu iki kere yazmamız gerekti. Ya varsa n kontrolör validators? Herbirinin iki (veya daha fazla) kopyasını tutmak zorunda mıyız?
  • User.find({ username }) iki kez tekrarlanır. Bu bir servis olabilir.

Sırasıyla Express ve Socket.io'nun tam tanımlarına ekli iki kontrolör yazdık. Büyük ihtimalle ömürleri boyunca asla kırılmayacaklar çünkü hem Express hem de Socket.io, geriye dönük uyumluluğa sahip olma eğilimindedir. FAKATYeniden kullanılamazlar. İçin Express değiştirme Hapi? Tüm kontrol cihazlarınızı tekrar yapmak zorunda kalacaksınız.

Bu kadar açık olmayabilir başka bir kötü koku ...

Denetleyici yanıtı el işi. .json({ error: whatever })

RL'deki API'ler sürekli olarak değişmektedir. Gelecekte cevabınızın olmasını isteyebilirsiniz. { err: whatever } ya da belki daha karmaşık (ve kullanışlı) gibi bir şey: { error: whatever, status: 500 }

Başlayalım (olası bir çözüm)

Onu arayamıyorum  çözüm çünkü orada sonsuz miktarda çözüm var. Yaratıcılığınıza ve ihtiyaçlarınıza bağlı. Aşağıdaki iyi bir çözümdür; Göreceli olarak büyük bir projede kullanıyorum ve iyi çalışıyor gibi görünüyor ve daha önce belirttiğim her şeyi düzeltir.

Modeli sonuna kadar ilginç tutmak için Model -> Servis -> Denetleyici -> Router'a gideceğim.

model

Model hakkında ayrıntılara girmeyeceğim, çünkü bu sorunun konusu değil.

Aşağıdaki gibi benzer bir Mongoose Model yapısına sahip olmalısınız:

Modeller / Kullanıcı / validate.js

export function validateUsername(username) {
  return true;
}

Mongoose 4.x validators için uygun yapı hakkında daha fazla bilgi edinebilirsiniz İşte.

Modeller / Kullanıcı / index.js

import { validateUsername } from './validate';

const userSchema = new Schema({
  username: { 
    type: String, 
    unique: true,
    validate: [{ validator: validateUsername, msg: 'Invalid username' }],
  },
}, { timestamps: true });

const User = mongoose.model('User', userSchema);

export default User;

Sadece bir kullanıcı adı alanına sahip temel bir Kullanıcı Şeması ve created  updated mongoose kontrollü alanlar.

Neden dahil ettim validate Buradaki alan, denetleyicide değil, burada çoğu model doğrulama işlemini gerçekleştirmeniz gerektiğini farketmeniz içindir.

MongoDN Schema, veritabanına ulaşmadan önceki son adımdır. Birisi doğrudan MongoDB'yi sorgulamadıkça, her zaman herkesin sizin model kontrollerinizden geçtiğinden emin olabilirsiniz, bu da onları kontrol cihazınıza yerleştirmekten daha fazla güvenlik sağlar. Önceki örnekte olduğu gibi birim test doğrulayıcıların önemsiz olduğunu söylememek.

Bu konuda daha fazla bilgi edinin İşte ve İşte.

Hizmet

Servis işlemci olarak hareket edecektir. Kabul edilebilir parametreler verildiğinde, bunları işleyecek ve bir değer döndürecektir.

Çoğu zaman (bunun dahil), faydalanacak Mongoose Modelleri ve geri dön Söz vermek (veya bir geri arama; Kesinlikle isterim Henüz yapmadıysanız ES6'yı Promises ile kullanın).

hizmet / user.js

function getUser(username) {
  return User.find({ username}).exec(); // Just as a mongoose reminder, .exec() on find 
                               // returns a Promise instead of the standard callback.
}

Bu noktada merak ediyor olabilirsiniz, hayır catchblok? Hayır, çünkü biz bir havalı hile daha sonra ve bu dava için özel bir ihtiyacımız yok.

Diğer zamanlarda, önemsiz bir senkronizasyon servisi yeterli olacaktır. Senkronizasyon hizmetinizin hiçbir zaman G / Ç içermediğinden emin olun, aksi takdirde engellenirsiniz tüm Node.js iş parçacığı.

hizmet / user.js

function isChucknorris(username) {
  return ['Chuck Norris', 'Jon Skeet'].indexOf(username) !== -1;
}

kontrolör

Yinelenen kontrolörlerden kaçınmak istiyoruz, bu yüzden sadece bir Her eylem için kontrolör.

kontrolörleri / user.js

export function getUser(username) {
}

Bu imza şimdi nasıl görünüyor? Güzel, değil mi? Sadece kullanıcı adı parametresiyle ilgilendiğimizden, req, res, next.

Kayıp doğrulayıcıları ve hizmeti ekleyelim:

kontrolörleri / user.js

import { getUser as getUserService } from '../services/user.js'

function getUser(username) {
  if (username === '') {
    throw new Error('Username can\'t be blank');
  }
  return getUserService(username);
}

Hala düzgün görünüyor, ama ... peki ya throw new ErrorBu benim uygulama çökmesine neden olmaz mı? - Şşş, bekle. Henüz bitirmedik.

Bu noktada, denetleyici dokümantasyonumuz şöyle görünüyordu:

/**
 * Get a user by username.
 * @param username a string value that represents user's username.
 * @returns A Promise, an exception or a value.
 */

Belirtilen "değer" nedir? @returns? Daha önce sunduğumuz hizmetlerin hem senkronizasyon hem de asenkronizasyon olduğunu Promise)? getUserService bu durumda asenkron isChucknorris Hizmet olmaz, bu nedenle bir Sözün yerine sadece bir değer döndürür.

Umarım herkes dokümanları okuyacaktır. Çünkü diğerlerinden farklı bazı denetleyicileri tedavi etmeleri gerekecek ve bazıları da try-catch blok.

Geliştiricilere (bu beni de içerir) ilk denemeden önce dokümanları okuyamayacağımıza göre, bu noktada bir karar vermek zorundayız:

  • Zorlamak için kontrolörler Promise dönüş
  • Her zaman bir söz vermek için servis

İn Bu tutarsız kontrolör dönüşünü çözecektir (try-catch bloğumuzu atlayamamamız gerçeği değil).

IMO, ilk seçeneği tercih ederim. Çünkü kontrolörler çoğu zaman en çok vaatleri zincirleyecek olanlardır.

return findUserByUsername
         .then((user) => getChat(user))
         .then((chat) => doSomethingElse(chat))

ES6 Promise kullanıyorsak, alternatif olarak güzel bir mülkün Promise böyle yaparak: Promise ömür boyu vaatlerini yerine getiremez ve yine de Promise:

return promise
         .then(() => nonPromise)
         .then(() => // I can keep on with a Promise.

Aradığımız tek hizmet kullanmazsa Promisebiz kendimizi yapabiliriz.

return Promise.resolve() // Initialize Promise for the first time.
  .then(() => isChucknorris('someone'));

Örneğimize geri dönecek olursak:

...
return Promise.resolve()
  .then(() => getUserService(username));

Aslında ihtiyacımız yok Promise.resolve() bu durumda getUserService zaten bir söz veriyor, ancak tutarlı olmak istiyoruz.

Eğer merak ediyorsan catch blok: özel bir işlem yapmak istemedikçe kontrol cihazımızda kullanmak istemiyoruz. Bu sayede mesajlarımızı tek tek kanallardan iletmek için halihazırda yerleşik olan iki iletişim kanalını (hatalar ve başarı mesajları için geri dönüş istisnası) kullanabiliriz.

ES6 Sözü Yerine .thenDaha yeni ES2017’yi kullanabiliriz async / await (şimdi resmi) kontrolörlerimizde:

async function myController() {
    const user = await findUserByUsername();
    const chat = await getChat(user);
    const somethingElse = doSomethingElse(chat);
    return somethingElse;
}

ihbar async önünde function.

Yönlendirici

Sonunda yönlendirici, yay!

Bu yüzden, henüz kullanıcıya bir şey yanıtlamadık, tek sahip olduğumuz, her zaman bir kontrolörün döndüğünü bildiğimiz bir denetleyici. Promise (umarım veri ile). Oh, ve bu muhtemelen bir istisna atarsa throw new Error is calledveya bazı servis Promise sonları.

Yönlendirici, tek tip bir şekilde, dilekçeleri kontrol edip müşterilere verileri döndürecek, mevcut bazı veriler olacak, null veya undefined  data veya bir hata.

Yönlendirici, SADECE çoklu tanımlara sahip olacak. Bunların sayısı bizim engelleyicilere bağlı olacaktır. Varsayımsal durumda, bunlar API (Express ile) ve Soket (Socket.io ile) idi.

Yapmamız gerekenleri gözden geçirelim:

Yönlendiricimizin dönüşümünü istiyoruz (req, res, next) içine (username). Bir naif versiyon şöyle bir şey olurdu:

router.get('users/:username', (req, res, next) => {
  try {
    const result = await getUser(req.params.username); // Remember: getUser is the controller.
    return res.status(200).json(result);
  } catch (error) {
    return res.status(500).json(error);
  }
});

Her ne kadar iyi çalışırsa da, bu snippet'i tüm rotalarımızda kopyalayıp yapıştırırsak, bu çok miktarda kod çoğaltmasıyla sonuçlanır. Bu yüzden daha iyi bir soyutlama yapmalıyız.

Bu durumda, söz veren bir tür sahte yönlendirici istemcisi oluşturabiliriz. n parametreleri ve yönlendirme ve return Görevler, tıpkı rotaların her birinde olduğu gibi.

/**
 * Handles controller execution and responds to user (API Express version).
 * Web socket has a similar handler implementation.
 * @param promise Controller Promise. I.e. getUser.
 * @param params A function (req, res, next), all of which are optional
 * that maps our desired controller parameters. I.e. (req) => [req.params.username, ...].
 */
const controllerHandler = (promise, params) => async (req, res, next) => {
  const boundParams = params ? params(req, res, next) : [];
  try {
    const result = await promise(...boundParams);
    return res.json(result || { message: 'OK' });
  } catch (error) {
    return res.status(500).json(error);
  }
};
const c = controllerHandler; // Just a name shortener.

Bu konuda daha fazla bilgi sahibi olmak istiyorsanız hile, diğer cevabımda bunun tam sürümünü okuyabilirsiniz. React-Redux ve Soket ile Websockets ("SocketClient.js" bölümü).

Rotanız nasıl görünür? controllerHandler?

router.get('users/:username', c(getUser, (req, res, next) => [req.params.username]));

Temiz bir satır, tıpkı başlangıçta olduğu gibi.

Diğer isteğe bağlı adımlar

Denetleyici sözleri

Sadece ES6 Promises kullananlara uygulanır. ES2017 async / await sürüm zaten bana iyi görünüyor.

Bazı nedenlerden dolayı kullanmak zorunda kalmaktan hoşlanmıyorum Promise.resolve() başlangıç ​​Promise oluşturmak için isim. Orada neler olup bittiği belli değil.

Daha anlaşılır bir şey için onları değiştirmeyi tercih ederim:

const chain = Promise.resolve(); // Write this as an external imported variable or a global.

chain
  .then(() => ...)
  .then(() => ...)

Şimdi bunu biliyorsun chain Promises zincirinin başlangıcını işaretler. Kodunuzu okuyan ya da olmasa bile, en azından bir zincirin bir hizmet işlevi olduğunu varsayar.

Express hata işleyicisi

Express, en az beklenmedik hataları yakalamak için kullanmanız gereken bir varsayılan hata işleyiciye sahiptir.

router.use((err, req, res, next) => {
  // Expected errors always throw Error.
  // Unexpected errors will either throw unexpected stuff or crash the application.
  if (Object.prototype.isPrototypeOf.call(Error.prototype, err)) {
    return res.status(err.status || 500).json({ error: err.message });
  }

  console.error('~~~ Unexpected error exception start ~~~');
  console.error(req);
  console.error(err);
  console.error('~~~ Unexpected error exception end ~~~');


  return res.status(500).json({ error: '⁽ƈ ͡ (ुŏ̥̥̥̥םŏ̥̥̥̥) ु' });
});

Dahası, muhtemelen böyle bir şey kullanmalısınız ayıklama veya winston yerine console.errorgünlükleri işlemek için daha profesyonel yollar.

Ve işte bunu nasıl yapıyoruz? controllerHandler:

  ...
  } catch (error) {
    return res.status(500) && next(error);
  }

Yakalanan her hatayı sadece Express 'hata işleyicisine yönlendiriyoruz.

ApiError olarak hata

Error Javascript'te bir istisna atarken hataların saklanması için varsayılan sınıf olarak kabul edilir. Gerçekten sadece kendi kontrol ettiğin hataları takip etmek istiyorsan, muhtemelen throw Error ve Express hata işleyicisinden Error için ApiErrorve hatta durum alanını ekleyerek ihtiyaçlarınızı daha iyi hale getirebilirsiniz.

export class ApiError {
  constructor(message, status = 500) {
    this.message = message;
    this.status = status;
  }
}

Ek bilgi

Özel istisnalar

Herhangi bir zamanda herhangi bir özel istisna atabilirsiniz. throw new Error('whatever') veya kullanarak new Promise((resolve, reject) => reject('whatever')). Sadece oynamak zorundasın Promise.

ES6 ES2017

Bu çok açık bir nokta. IMO ES6 (ya da ES2017şimdi, resmi bir özellikler kümesine sahip olmak, Düğüme dayalı büyük projeler üzerinde çalışmak için uygun bir yoldur.

Henüz kullanmadıysanız, bakmayı deneyin. ES6 özellikleri ve ES2017 ve Babil transpiler.

Sonuç

Bu herhangi bir yorum veya ek açıklama olmadan sadece tam kod (daha önce gösterilmiştir). Bu bölümle ilgili her şeyi, ilgili bölüme kadar kaydırarak kontrol edebilirsiniz.

router.js

const controllerHandler = (promise, params) => async (req, res, next) => {
  const boundParams = params ? params(req, res, next) : [];
  try {
    const result = await promise(...boundParams);
    return res.json(result || { message: 'OK' });
  } catch (error) {
    return res.status(500) && next(error);
  }
};
const c = controllerHandler;

router.get('/users/:username', c(getUser, (req, res, next) => [req.params.username]));

kontrolörleri / user.js

import { serviceFunction } from service/user.js
export async function getUser(username) {
  const user = await findUserByUsername();
  const chat = await getChat(user);
  const somethingElse = doSomethingElse(chat);
  return somethingElse;
}

hizmet / user.js

import User from '../models/User';
export function getUser(username) {
  return User.find({}).exec();
}

Modeller / Kullanıcı / index.js

import { validateUsername } from './validate';

const userSchema = new Schema({
  username: { 
    type: String, 
    unique: true,
    validate: [{ validator: validateUsername, msg: 'Invalid username' }],
  },
}, { timestamps: true });

const User = mongoose.model('User', userSchema);

export default User;

Modeller / Kullanıcı / validate.js

export function validateUsername(username) {
  return true;
}

51
2018-02-10 16:28



Ben beğendim senin controllerHandler hile. Şablon altyapısını kullanarak biraz görüntü oluşturmak istiyorsam lütfen bana öneride bulunabilir misiniz? demek istediğim res.render('index', {title: 'Hello'}). Bu durumda Kontrolör ve Rota nasıl görünmelidir? - MyTitle
@MyTitle Kontrolörleri değiştirmekten kaçınırdım. {title: 'Hello'} halihazırda gönderilen mevcut nesne değerleri olabilir handleController. 'index' muhtemelen üzerinde ekstra bir parametre olmalı handleController işlevi, hiçbir denetleyici sonucu işlemek için görünümüyle ilgilenmediğinden. İhtiyaçlarınıza bağlı olarak, farklı türdeki sonuçları veya hataları işlemek için 2 veya daha fazla görüntüyü geçmek isteyebilirsiniz, ancak bununla başlayabilmek için sadece bir görüntüleme dosyasının adını aktarıyorum ve sonra "Express Error Handler" da bir varsayılan hata var "(şu anda res.json). - zurfyx
Bu harika. Teşekkür ederim. - Dheeraj Kumar


Herkesin projeyi belirli klasörlere ayırma yolu vardır. Kullandığım yapı

  • yapılandırma
  • günlükleri
  • rotalar
  • kontrolörleri
  • modeller
  • Hizmetler
  • utils
  • app.js / server.js / index.js (tercih ettiğiniz herhangi bir isim)

config klasörü, "production", "development", "testing" gibi tüm geliştirme aşamaları için veritabanı bağlantı ayarları gibi yapılandırma dosyalarını içerir.

örnek

'use strict'
var dbsettings = {
    "production": {
//your test settings
    },
    "test": {

    },
    "development": {
        "database": "be",
        "username": "yourname",
        "password": "yourpassword",
        "host": "localhost",
        "connectionLimit": 100
    }
}
module.exports = dbsettings

log klasörü hata ayıklama için bağlantı günlükleri hata günlüklerini içerir

denetleyici, req verilerinizi ve iş mantığınızı doğrulamak içindir

örnek

const service = require("../../service")
const async = require("async")
exports.techverify = (data, callback) => {

    async.series([
        (cb) => {
            let searchObject = { accessToken: data.accessToken }
            service.admin.get(searchObject, (err, result) => {
                if (err || result.length == 0) {
                    callback(err, { message: "accessToken is invalid" })
                } else {
                    delete data.accessToken
                    service.tech.update(data, { verified: true }, (err, affe, res) => {
                        if (!err)
                            callback(err, { message: "verification done" })
                        else
                            callback(err, { message: "error occured" })
                    })
                }
            })
        }
    ])
}

modeller db şemanızı tanımlamak içindir

örnek mongoDb şeması

'use strict'
let mongoose = require('mongoose');
let schema = mongoose.Schema;
let user = new schema({
    accesstoken: { type: String },
    firstname: { type: String },
    lastname: { type: String },
    email: { type: String, unique: true },
    image: { type: String },
    phoneNo: { type: String },
    gender: { type: String },
    deviceType: { type: String },
    password: { type: String },
    regAddress: { type: String },
    pincode: { type: String },
    fbId: { type: String, default: 0 },
    created_at: { type: Date, default: Date.now },
    updated_at: { type: Date, default: Date.now },
    one_time_password: { type: String },
    forgot_password_token: { type: String },
    is_block: { type: Boolean, default: 0 },
    skin_type: { type: String },
    hair_length: { type: String },
    hair_type: { type: String },
    credits: { type: Number, default: 0 },
    invite_code: { type: String },
    refered_by: { type: String },
    card_details: [{
        card_type: { type: String },
        card_no: { type: String },
        card_cv_no: { type: String },
        created_at: { type: Date }
    }]
});
module.exports = mongoose.model('user', user);

hizmetler veri tabanı sorgunuzu yazmak içindir Denetleyicideki sorguları yazmaktan kaçının Bu klasörde sorgu yazmayı deneyin ve denetleyicide arayın

Mongoose kullanarak sorgular

'use strict'
const modelUser = require('../../models/user');
exports.insert = (data, callback) => {
    console.log('mongo log for insert function', data)
    new modelUser(data).save(callback)
}
exports.get = (data, callback) => {
    console.log('mongo log for get function', data)
    modelUser.find(data, callback)
}
exports.update = (data, updateData, callback) => {
    console.log('mongo log for update function', data)
    modelUser.update(data, updateData, callback);
}
exports.getWithProjection = (data, projection, callback) => {
    console.log('mongo log for get function', data)
    modelUser.find(data, projection, callback)
}

utils, şifrelemek, şifre şifresini çözmek gibi projenizde yaygın olarak kullanılan ortak fayda fonksiyonu içindir.

örnek

exports.checkPassword = (text, psypherText) => {
    console.log("checkPassword executed")
    console.log(text, psypherText)
    return bcrypt.compareSync(text, psypherText)
}
exports.generateToken = (userEmail) => {
    return jwt.sign({ unique: userEmail, timeStamp: Date.now }, config.keys.jsonwebtoken)
}

3
2018-02-09 18:01





rohit salaria'nın cevabı temel olarak java'da kullandığınız aynı uygulama yapısını açıklıyor.

  • Kontrolörler Java'daki Kontrolörlerdir
  • Modeller Veri Erişimi Katmanıdır
  • Hizmetler Hizmet Katmanıdır

Yine de birkaç sözüm var. İlk ve en önemlisi, bu Java değil. Açık görünebilir, ancak sorunuza bakın ve Java dünyasında kullandığınız aynı kavramlarla aynı gelişim deneyimine baktığınızı görün. Aşağıdaki açıklamalarım bunun açıklamasıdır.

Eksik DTO'lar. Java'da sadece gerekli, dönem. Verilerinizi ilişkisel bir veritabanında depoladığınız ve JSON'da ön uça veri gönderip aldığınız bir Java web uygulamasında, verileri bir Java nesnesine dönüştürmeniz doğaldır. Ancak bir Düğüm uygulamasında her şey javascript ve JSON. Bu platformun güçlü yanlarından biri. JSON'un ortak veri formatı olması sayesinde, kod yazmak veya katmanlarınızın veri formatı arasında çeviri yapmak için kütüphanelere bağlı olmak gerekmez.

Veri nesnesini doğrudan istek üzerine modele geçirme. Neden olmasın? Ön uçtan veritabanına ortak veri formatı olarak JSON'a sahip olmak, uygulamanızın veri modelini tüm katmanlarınız arasında kolayca senkronize etmenizi sağlar. Tabi ki bu şekilde gitmek zorunda değilsiniz, ama çoğu zaman yeterlidir, o yüzden neden kullanmıyorsunuz? Doğrulama gelince, MVC teorisine göre ait olduğu modelde (tembellik ve pragmatizmin sık sık koydukları kontrolörde değil :) yapılır.

Eklemek istediğim son düşünce için, proje boyutu ölçeklendirme söz konusu olduğunda bu en iyi platform değil. Bu hiç yaramadı, ama Java bu açıdan daha iyidir.


0
2018-02-09 19:40





Yapmaya çalıştığın şeyi başardım. Esasen geleneksel Rota / Kontrolör / Model yapısında eksik bir katman var. Kısa cevap, bu, düğüm alanında henüz nasıl olmasını istemediğidir - bu yüzden nesneleri manipüle etmek istiyorsanız yapılacak özel şeyler gelir.

Başlamak için birkaç öneri:

  • Hisse senedi JavaScript yerine TypeScript kullanın
  • Express'i HapiJS ile değiştirin

Bu hedefe ulaşmak için bulduğum en etkili yol, modele erişen ve sonra bunları denetleyicilerinize aktaran statik yöntemlere sahip bir nesneye sahip olmaktır. Şimdi - bu, düğüm sunucularındaki dokümanları takip etmekten çok daha fazla zaman alıyor - ama işiniz bittiğinde, bakımı çok basit ve büyük ekipler için iş bölümü ayrımı harikadır (bir kez ekip tam olarak rotalara ayrılabilir) kontrol cihazları ise DAO / modelleri yönetir.

// controller
import Article from 'models/Article';
export ArticleController {

    class GET {
        handler( req, res ){
            return Article.find(req.params.id);
        }
    }

    class POST {

        validator: {
            // this is where you ensure req.payload is going to be sufficient for the article constructor
            payload: {
                name: joi.string().required()
            }
        }

        handler( req, res ){
            const oArticle = new Article(req.payload);
            oArticle.save();
        }
    }

}

//Article
export class Article {
    public id: string;
    public name: string;

    constructor(data){
        // over-simplified logic to load data into object for example
        // there are some edge cases you need to figure out
        Object.assign(this, data);
    }

    public static find( id ){
       // get the article from your DAO - pseudo code
       const data = DAO.getArticleDataById(id);
       return new Article(data);
    }

    public save(){
        // save this object using DAO
    }
}

0
2018-02-10 07:26





basit ve basit kural

  1. Bileşenleri birbirine yakın tutun.

  2. Sayfayı bileşenlere ayırın ve çalışın

  3. Tüm bağımlı bileşenler birlikte olmalı

  4. Paylaşılan şeyler diğer tüm bileşenlerden bağımsız tutulmalıdır.

Sonunda her dil tatlıdır. Sadece bu dil ile ne kadar tanıdık olduğunu. Sadece size kılıç tanıdık eğer savaşı kazanabilirsiniz.

Ben NodeJS kullanarak Angular2 uygulama geliştiriyorum, Angular2 Ben dizin yapısı ile size yardımcı olacağım.

main Module

ana modül 

subModule

 alt modül yapısı

shared Module

`paylaşımlı klasörü ayrı bir modül olarak tutun

Umarım yardımcı olur :)


0
2018-02-13 11:23