私はNode(および一般的にすべてのバックエンドWeb開発)の初心者であり、NodeでRESTful APIの記述を開始しました。取得しようとしていることがいくつかあります。私の頭の周り。
私のアプリケーションはExpressとMongooseを使用しており、express-resource
モジュールは、APIリソースのCRUDルートを簡単に作成します。しかし、私が不満を抱いていることがいくつかあります。
最初はマングースです。 APIのテストを作成する場合、Mongooseをスタブしてメモリデータに強制する方法はありません。ただし、そこにあるすべてのチュートリアルはMongooseを指しているようで、実際に何を使用すべきかはわかりません。
第二に、私のリソースには定型的なコードがたくさんあるようです。これは本当にNode.jsでRESTful APIを作成する最良の方法ですか? CRUDルートの作成に役立つ他のモジュールはありますか?コードを使用せずにスキーマから直接CRUDルートを作成する方法はあると思いますが、どのようにすればよいのかよくわかりません。
Tower.jsやCompoundJS(以前はRailwayJS)などのプロジェクトを見てきました。これらのプロジェクトは、ここでの私の問題をはるかに解決する包括的なソリューションのようです。おそらくそれらを使用する必要がありますが、実際にはNode.jsアプリケーションのみをAPIにしたいのです。 APIとは無関係にフロントエンドを扱っています。
コンテキストを提供するために、ここに私の現在の状況があります。現在、私はMongooseでモデルを定義しています:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, Link
var LinkSchema = new Schema({
uri: String,
meta: {
title: String,
desc: String
},
shares: [{
uid: Schema.Types.ObjectId,
date: Date,
message: String
}]
})
Link = module.exports = mongoose.model('Link')
次に、CRUDルートのコントローラーを定義します。
var mongoose = require('mongoose')
, _ = require('underscore')
, Link = mongoose.model('Link')
exports.load = function (req, id, fn) {
Link.findById(req.params.link, function (err, link) {
if (err) {
return res.send(err)
}
fn(null, link)
})
}
exports.index = function (req, res) {
var filterByUser = req.query.user ? { 'shares.uid': req.query.user } : {}
Link.find(filterByUser, function (err, links) {
if (err) {
return res.send(err)
}
res.send(links)
})
}
exports.create = function (req, res) {
var link = new Link(req.body)
link.save(function (err) {
if (err) {
// TODO: send 404
return res.send(err)
}
res.send(link)
})
}
exports.show = function (req, res) {
res.send(req.link)
}
exports.update = function (req, res) {
req.link = _(req.link).extend(req.body)
req.link.save(function (err, link) {
if (err) {
return res.send(err)
}
res.send(link)
})
}
exports.patch = exports.update
exports.destroy = function (req, res) {
req.link.remove(function (err) {
if (err) {
return res.send(err)
}
res.send()
})
}
最後に、express-resource
これらのコントローラーをExpressアプリの上にある必要なCRUDルートにマップするモジュール。
app.resource('api/links', require('../resources/links'))
restify を調べる必要があります
エクスプレスを使用する場合は、 node-restful と呼ばれるこのプロジェクトをチェックアウトすることもできます。
このライブラリははるかに成熟しており、より多くの機能を備えているようです: https://github.com/jspears/mers
Strongloop Loopback は、Node/MongoDB APIを生成するための別の優れた代替手段のようです。 mocha tests も生成できます。
Hapi をご覧ください。WebアプリケーションとAPIを構築するための構成中心のフレームワークであり、安らかなサービスとして使用されます。
他のオプションは sails.js および actionhero です
Strapi は新しい(2015)フレームワークです。
Webサイトの管理インターフェイスを使用すると、APIを作成し、モデル間の関係を指定できます。 (紹介ビデオで見られるように。)
ただし、ExpressではなくKoaサーバーで実行するように設計されています。
ここに、最近のフレームワークに関する問題があります。
Googleから「最高」、「最速」のフレームワークを何とか検索すると、人々は「おい、このsails.js、羽、ダービーなどを試してみてください...」
質問は次のとおりです。-それらのフレームワークをただ楽しんでいますか-はいの場合、フレームワークのリストを簡単に取得して、それらのベンチマークを開始できます。
ここでキーワードと注意を検索するのはすべて間違っています。「プロダクション準備完了」、「エンタープライズ準備完了」、「ケーススタディ」でそれらのキーワードを検索するか、またはIndeed.comにアクセスしてnode.jsを検索し、ほとんどの企業が使用しているnode.jsフレームワーク、答えは単に「エクスプレス」と言うだけかもしれません。
もしそうなら、node.jsスタックから、フレームワークはそれらのいくつかをかなり絞り込みます:Hapi、Strongloop、または人気のないYahooのMojito
少なくともこれらのフレームワークについては、「彼らは実際に本番またはエンタープライズ対応です」と言うことができます-彼らはしばらくの間、ヤフーから、他の大巨人からのウォルマートのフォームを使用していました。
これはなぜRuby on Rails and Djangoがまだスタックフレームワーク市場全体を支配していますか? Meteor、Sails.js、Go's Revel、Java's Play Sparkあなたが名付けられるものなら何でも-これらのフレームワークが2つより悪いということではなく、ただ彼らは市場に勝つために時間が必要です。
現在のフレームワークの多くの別の問題は、一種のオールインワンの「Ror」のクローンです。エンドユーザーの見通しから、彼らは物事を成し遂げるのに役立つもの、生産性が必要、最初から最後まで何かを必要とする、例えばRuby on Rails、MacOSなど、窓は、それまでにテストされたもの自体と同様に、人々が毎日使用しています。
Baucis + Expressをお勧めします。何千人ものユーザー、Mongooseに基づくモデル駆動型設計、非常に柔軟で仕様に準拠、HATEOAS/Level 3対応。私のすべてのニーズに完璧に適合します。しかし、その後、私は著者です:) https://github.com/wprl/baucis
https://hivepod.io/ を試して、完全なMEANスタックで例を生成してください。 Hivepodは、BaucisJS + ExpressJS + MongoDB + AngularJSの上に構築されます。
免責事項:私はHivepodの構築に取り組んでいます。
var mongoose = require('../DBSchema/SchemaMapper');
var UserSchema = mongoose.model('User');
var UserController = function(){
this.insert = (data) => {
return new Promise((resolve, reject) => {
var user = new UserSchema({
userName: data.userName,
password: data.password
});
user.save().then(() => {
resolve({status: 200, message: "Added new user"});
}).catch(err => {
reject({status: 500, message: "Error:- "+err});
})
})
}
this.update = (id, data) => {
return new Promise((resolve, reject) => {
UserSchema.update({_id: id}, data).then(() => {
resolve({status: 200, message: "update user"});
}).catch(err => {
reject({status: 500, message: "Error:- " + err});
})
})
}
this.searchAll = () => {
return new Promise((resolve, reject) => {
UserSchema.find().exec().then((data) => {
resolve({status: 200, data: data});
}).catch(err => {
reject({status: 500, message: "Error:- " + err});
})
})
}
this.search = (id) => {
return new Promise((resolve, reject) => {
UserSchema.find({_id:id}).exec().then(user => {
resolve({status: 200, data: user});
}).catch(err => {
reject({status: 500, message: "Error:- " + err});
})
})
}
this.delete = (id) => {
return new Promise((resolve, reject) => {
UserSchema.remove({_id:id}).then(() => {
resolve({status: 200, message: "remove user"});
}).catch(err => {
reject({status: 500, message:"Error:- " + err});
})
})
}
}
module.exports = new UserController();
///Route
var express = require('express');
var router = express.Router();
var Controller = require('./User.Controller');
router.post('/', (req, res) => {
Controller.insert(req.body).then(data => {
res.status(data.status).send({message: data.message});
}).catch(err => {
res.status(err.status).send({message: err.message});
})
});
router.put('/:id', (req, res) => {
Controller.update(req.params.id, req.body).then(data => {
res.status(data.status).send({message: data.message});
}).catch(err => {
res.status(err.status).send({message: err.message});
})
});
router.get('/', (req, res) => {
Controller.searchAll().then(data => {
res.status(data.status).send({data: data.data});
}).catch(err => {
res.status(err.status).send({message: err.message});
});
});
router.get('/:id', (req, res) => {
Controller.search(req.params.id).then(data => {
res.status(data.status).send({data: data.data});
}).catch(err => {
res.status(err.status).send({message: err.message});
});
});
router.delete('/:id', (req, res) => {
Controller.delete(req.params.id).then(data => {
res.status(data.status).send({message: data.message});
}).catch(err => {
res.status(err.status).send({message: err.message});
})
})
module.exports = router;
//db`enter code here`schema
var mongoose = require('mongoose');
const Schema = mongoose.Schema;
var Supplier =new Schema({
itemId:{
type:String,
required:true
},
brand:{
type:String,
required:true
},
pno:{
type:String,
required:true
},
email:{
type:String,
required:true
}
});
mongoose.model('Inventory',Inventory);
mongoose.model('Supplier',Supplier);
mongoose.connect('mongodb://127.0.0.1:27017/LAB', function (err) {
if (err) {
console.log(err);
process.exit(-1);
}
console.log("Connected to the db");
});
module.exports = mongoose;
これは、ライブラリシステムでCRUD操作を実行するためのサンプルです
var schema=require('../dbSchema');
var bookmodel=schema.model('book');
exports.getBooks = function (req,res) {
bookmodel.find().exec().then((data)=>{
res.send(data)
}).catch((err)=>{
console.log(err);
});
};
exports.getBook = function (req,res) {
var bkName=req.params.Author;
bookmodel.find({Name:bkName}).exec().then((data)=>{
res.send(data)
}).catch((err)=>{
console.log(err);
});
};
exports.getAutBooks = function (req,res) {
bookmodel.find({},'Author').then((data)=>{
res.send(data);
}).catch((err)=>{
console.log(err);
});
};
exports.deleteBooks=function(req,res){
var bkName=req.params.name;
bookmodel.remove({Name:bkName}).exec().then((data)=>{
res.status(200);
console.log(bkName);
}).catch((err)=>{
console.log(err);
});
};
exports.addBooks=function(req,res){
var newBook=new bookmodel({
Name:req.body.Name,
ISBN:req.body.ISBN,
Author:req.body.Author,
Price:req.body.Price,
Year:req.body.Year,
Publisher:req.body.Publisher
});
newBook.save().then(()=>{
res.status(201);
}).catch((err)=>{
console.log(err);
});
};
Expressを使用してNode.jsでRESTful APIを構築してきましたが、Express 4にルーターを追加すると、構造化がさらに簡単になりました。詳細はこちら http://www.codekitchen.ca/guide-to-structuring-and-building-a-restful-api-using-express-4/
これを見てください link
このプロジェクトは、ASP.Net WebApi 2.0が後に続く同じプロジェクトアーキテクチャを使用してビルドされます。つまり、最初にコントローラー、認証メカニズムなどを使用することになります。必要なことは、独自のコントローラーを作成することだけです。
私はExpressの大ファンであり、それを使用してNode.jsでRESTful APIを構築し、構築しやすくしています。しかし、アプリケーションが成長し始めたとき、エクスプレス構造がうまくスケールしない状況で終わり、コード分割が増えたため、メンテナンスが難しくなりました。
私は、C#/ Javaのバックグラウンドで、SOLID原則が頻繁に使用されています。Java Spring / C# WebAPI
は、エンタープライズレベルのアプリケーションを作成することが実証されています。既存のC#/ Javaスキルを再利用できるフレームワークが欲しかった(reuse I mean MVC architecture, OOPS, SOLID, DI, Mocks ... yeah, strong typing
)。残念ながら、要件を満たすフレームワークが見つかりませんでした(It should have less learning curve, minimalist codebase size, completely express compatible
)。
完全に互換性があるとはどういう意味ですか?Expressが何をするにしても、その上にフレームワークを使用している場合でも、私は Strongloop Loopback を調べましたが、使用するのはかなり良かったのですが、多くのドキュメントがあり、フレームワークが結合されていて、実際に探していたものではありません。
Dinoloop Powered by TypeScript(has interfaces, classes, abstract classes and strong oops
)。パッケージは現在かなり安定しています。
Dinoloopを使用すると、スケーラブルなアーキテクチャでエンタープライズレベルのアプリケーションを構築できます。 Dependency Injectionフレームワークを使用しますが、TypeScriptで利用可能なDIフレームワークを設定できます。 Dinoloopにより、TypeScriptがNodejs RESTフレームワークとして使用できるようになり、angular
およびnode
プロジェクトの両方で共通のTypeScriptコードベースを維持できました。
したがって、Dinoloopは、TypeScriptの愛好家やangular開発者に最適です。
誰も言及していないことに驚いています Nodal 。
ウェブサイトから:
NodalはNode.js用のWebサーバーであり、APIサービスを迅速かつ効率的に構築するために最適化されています。
独自の意見があり、明示的で、慣用的で、高度に拡張可能なフレームワークを誇るNodalは、あなたとあなたのチームのすべての難しい決定を引き受けます。これにより、技術的な負債を最小限に抑えながら、短期間で効果的な製品を作成することに集中できます。
積極的に保守され、Githubに3800以上の星を付け(執筆時点)、ボイラープレートコードを生成するためのコマンドラインツールが組み込まれており、全体として作業を迅速に完了します。