Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9360

フロントサーバ、バックサーバの分離された構成でミニマムなサービスを作る。

$
0
0

はじめに

本記事はモノリシックでない分離されたアーキテクチャ(マイクロサービス)について理解を深めるため、
ミニマムなアプリを作ってみたときのまとめ記事です。
※当方初心者のため、間違いありましたら是非ともご指摘お願いいたします。

著者について

以下著者のスペック

  • エンジニア一年目
  • WebアプリといえばMVCしか知らない
  • マイクロサービス?なにそれおいしいの

背景

基本情報などの勉強中、よくこんな図が出てきて混乱していました。

image.png

  • Webアプリのアーキテクチャ?、MVCしかしらんけど?
  • アプリのサーバって一つだけじゃないの?
  • でもReactとかは独立してサーバーが立っているぽい、、
  • どうやってバックエンドと連携させるんやろ、、?

このような疑問を持った私は、「わかんないなら触ってみればいいじゃん!」と意気込み、
フロントエンドとバックエンドの機能をサーバごとに切り離したミニマムなアプリを作ろうと決めました。

開発

概要

画面を担当するフロントサーバとロジックを担当するバックサーバの二つのサーバを立てて、
インターネットのニュースを検索できるアプリを作る。

環境

  • Node.js v14.15.1

    • サーバサイドのJavaScript
    • こちらの記事が非常にわかりやすくおすすめ
    • 今回は超簡単なロジックを実装するのみに使う
  • Express v4.17.1

    • Node.jsで動く軽量なWebフレームワーク
    • Webサーバを立てるのも非常に簡単
    • 今回はAPIのルーティング等に使う
  • Yarn v1.22.4

    • npmと互換性があるパッケージ管理システム
    • 一度インストールしたパッケージをキャッシュするためインストールが高速

目標

画像のような簡単なニュース検索アプリを作る。
検索条件を入れ、「Search」ボタンを押下すれば、検索条件にヒットするニュースを検索する。
image.png

構成

本アプリの構成を以下画像に示します。
image.png

重要であるのはフロントサーバとバックサーバをAPIで疎結合している点です。
フロントサーバはバックサーバのAPIを呼び出し、返却されたレスポンスをもとに画面描画をします。

手順

バックサーバの実装

Node.js, Expressの解説は目的ではないため、重要な部分(独自APIを実装する部分)のみ示します。
以下はExpressでサーバを起動する部分です。

backend/server.js
'use strict';constexpress=require('express');constapp=express();constcors=require('cors');constdotenv=require('dotenv');dotenv.config({path:'./.env'});constmorgan=require('morgan');// CORS(クロスオリジンリソース共有)を許可app.use(cors());require('./routes/news')(app);// アクセスロガーを実装app.use(morgan('dev'));// サーバをポート3000で起動app.listen(process.env.PORT,()=>console.log('listening on port '+process.env.PORT));module.exports=app;

ここではCORS(クロスオリジン間リソース共有)を有効にしています。
CORSについては自分もよく理解しきれていないですがMDNに以下のような説明があります。

オリジン間リソース共有Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

こちらの記事が詳しいため参考にしてください。

次はインターネットからニュースの情報を取得する処理です。
ここではNews APIというAPIを本アプリ用にラップしています。

backend/routes/news.js
constNewsAPI=require('newsapi');constnewsapi=newNewsAPI(process.env.NEWS_API_ACCESS_KEY);constmorgam=require('morgan');constrouter=require('express').Router();module.exports=(app)=>{router.route('/').get((req,res)=>res.json({message:'This is a index page.'}));router.route('/news').get((req,res)=>{newsapi.v2.topHeadlines({// 検索条件が指定されなかった場合はデフォルトの条件を指定する。country:req.query.country||'jp',category:req.query.category||'general',q:req.query.q||'',pageSize:Number(req.query.pageSize)||30}).then(news=>res.json(news));});//bind access loggerapp.use(morgam('dev'));app.use(router);};

フロントサーバの実装

こちらもReactの解説は目的でないため、重要な部分(バックサーバと通信する部分)のみ示します。
またcreate-react-appを使用してテンプレを作成しました。

以下はバックサーバのAPIを呼び出し、返却されたニュース一覧のJSONを画面上の変数に渡しています。

frontend/src/App.js
consthandleSubmit=asyncevent=>{// submitボタンを押すとブラウザのデフォルトでリロードされてしまうため// デフォルトの動作をさせないよう設定するevent.preventDefault();// バックサーバのAPIを呼び出すletarticlesArr=awaitaxios.get(endPoint+'/news',{// 画面に入力された検索条件を独自APIのリクエストに乗せる params:{country:country.value,category:category.value,q:keyword,pageSize:pageSize.value}})// データが返却されたら変数articlesArrにデータを代入する。.then(res=>res.data.articles);// 画面上の変数にデータを代入する。setArticles(articlesArr);};

完成品

ソースは以下においてあります。
https://github.com/yasuaki640/news-api-app

※コードレビュー歓迎

終わりに

業務でも趣味でもモノリシックなアーキテクチャしか触ったことがなく、
ツイッター上でマイクロサービスなどの用語を理解するのに時間がかかりました。
※現在は完全に理解した程度

技術理解のために実際に触れてみるのはやはり強いですね、、、
本記事がどなたかのお役に立てれば幸いです。
※間違いありましたら是非ご指摘お願いいたします。


Viewing all articles
Browse latest Browse all 9360

Trending Articles