DOSの次の永続的です.7分でDETA基地


次.JSは、反応の上に多くを加えます;ボックスのServerless関数を使用してAPIのルートをサポートし、次の伝統的なサーバー側のタスクを行うには、データベースに認証要求を行うようにしましょう.展開するならVercel , the pages/api ディレクトリは自動的に関数として展開されます.
我々が以前に話したように、伝統的なデータベースは、永続的な接続が非同期で、一時的な機能とよく噛み合わないところですベセルは示唆するconnection pooling これらの問題を緩和する一つの方法として.データベース要求が永続的なデータベース接続に依存しない純粋なServerlessなデータベースを使用することはこの問題の別の方法です.
このチュートリアルでは、次を使用してアプリケーションを行うに作成をご案内します.JERSとDETA基地、Vercelで展開.このアプリは基本的にクライアント側の状態モデルをどこで行うには、唯一の反応コンポーネントに格納されます.このアプリでは、Serverless機能は、DTAのベースには、状態を行うには、話をします.これはDOSにコンポーネントunmountを越えて広がる持続性を提供するでしょう、そして、見られるように、DO状態に更新するのに用いられることができて、私たちの次にフィードバックします.jsアプリ.
このアプリはCreate Next App スターター、および完全なソースコードはhere .
命令の展開here .

デザイン


アプリケーションの基本単位は、JSONオブジェクトとして存在するものです.
{
    "content": "Wake Up On Time", // string
    "isCompleted": false // boolean
}
これらはDTAベースに格納され、最終的に次のレンダリングされます.jsアプリ.そのためにはdeta プロジェクトへの依存npm install deta or yarn add deta .
その上、我々の次.JSのアプリを生成し、このデータと対話することができる必要があります.つの基本的なCRUD関数を2つのエンドポイント/Serverless関数にネクストすることができます.js
  • 新しい方法を作成します.POST api/todos
  • DOSにすべてを読んでください.GET api/todos
  • idを行うtid ): PUT api/todos/{tid}
  • IDを削除するtid ): DELETE api/todos/{tid}
  • 次は基本.我々のアプリケーションのためのJSファイル構造は以下の通りですCreate Next App スターター.
    /pages
        index.js (our frontend logic)
        /api
                /todos
                    index.js (function, will handle the GET & POST)
                    [tid].js (function, will handle the PUT & DELETE)
    
    

    Aを行う


    するには、呼び出しを行うAPI呼び出しを作成しましょうPOST api/todos いくつかに基づきますnewContent 反応状態フックに格納されるinput element in line 84 ):
    export default function Home() {
    
      const [newContent, setNewContent] = useState('');
    
      ...
    
    
      const createToDo = async () => {
        const resp = await fetch('api/todos', 
          {
            method: 'post', 
            body: JSON.stringify({content: newText})
          }
        );
        // await getToDos(); To Be Implemented
      }
    
        ...
        return (
        ...
                <input className={styles.inpt} onChange={e => setNewContent(e.target.value)}></input>
        ...
        )
    
    }
    
    機能createToDo , 呼び出されると、newContent 反応の状態からPOST それは私たちのエンドポイントにpages/api/todos/index.js ( link here ):
    // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
    import { Deta } from 'deta';
    
    const deta = Deta(process.env.DETA_PROJECT_KEY);
    
    const base = deta.Base('todos');
    
    export default async (req, res) => {
      let { body, method } = req;
      let respBody = {};
    
      if (method === 'GET') {
    
        // To Be Implemented
    
      } else if (method === 'POST') {
    
        body = JSON.parse(body);
        body.isCompleted = false;
        respBody = await base.put(body);
        res.statusCode = 201;
    
      }
    
      res.json(respBody);
    }
    
    このハンドラではproject key 我々が得るからDeta に格納するVercel Environment Variable . このキーは、DETAプロジェクトの任意の基地に話をすることができますtodos . 使用Deta SDK , 私たちはcontent API呼び出しからisCompleted フィールドを使用し、put データベースに新しいDOを格納する方法.キーが自動的にこの項目が格納されるの下に生成されます.

    DOSへの読み込み


    すべてのDOSを読むには、呼び出しを行うAPI呼び出しを作成しましょうGET api/todos のホームコンポーネントの反応フックに格納pages/index.js .
    第二に、反応を使いましょうuseEffect フックは、コンポーネントがマウントされたときにこの関数を呼び出します.
    第三に、我々は我々のアプリ(ラインの異なる部分で表示される完了ステータスによってDOSのリストを与える)に私たちのDOSから2つのリストを作成してみましょう89 and 106 of index.js ).
    これは我々の仕事をしているToDo component , 我々は正しく、現在のコンテンツと完了ステータスを表示すると仮定します.
    export default function Home() {
    
      const [newContent, setNewContent] = useState('');
    
      const [toDos, setToDos] = useState([]);
    
      const getToDos = async () => {
        const resp = await fetch('api/todos');
        const toDos = await resp.json();
        setToDos(toDos);
      }
    
        ...
    
      useEffect(() => {
        getToDos();
      }, [])
    
      const completed = toDos.filter(todo => todo.isCompleted);
      const notCompleted = toDos.filter(todo => !todo.isCompleted);
    
        ...
    
      return (
    
        ...
    
         <div className={styles.scrolly}>
            {notCompleted.map((todo, index) => 
              <ToDo 
                key={todo.key} 
                content={`${index + 1}. ${todo.content}`} 
                isCompleted={todo.isCompleted} 
                // onChange={() => updateToDo(todo)} To Be Implemented
                // onDelete={() => deleteToDo(todo.key)} To Be Implemented
              />
            )}
         </div>
    
        ...
    
         <div className={styles.scrolly}>
           {completed.map((todo, index) => 
             <ToDo 
               key={todo.key} 
               content={`${index + 1}. ${todo.content}`} 
               isCompleted={todo.isCompleted}
               // onChange={() => updateToDo(todo)} To Be Implemented
               // onDelete={() => deleteToDo(todo.key)} To Be Implemented
             />
           )}
        </div>
    
        ...
    
        )
    
    }       
    
    のサーバレス関数ハンドラpages/api/todos/index.js 下記のように見えます.
    // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
    import { Deta } from 'deta';
    
    const deta = Deta(process.env.DETA_PROJECT_KEY);
    
    const base = deta.Base('todos');
    
    export default async (req, res) => {
      let { body, method } = req;
      let respBody = {};
    
      if (method === 'GET') {
    
        const {value: items} = await base.fetch([]).next();
        respBody = items;
        res.statusCode = 200;
    
      }
    
    ...
    
      res.json(respBody);
    }
    
    ヒアGET リクエストは関数Deta Base's fetch データベース内のすべての項目を返すにはtodos .

    Aを行う


    Doの完了ステータスを更新するには、関数を作成しますupdateToDo それでPUT api/todos/{tid} 我々のtodoコンポーネントに基づいてonChange 関数(チェックボックスでチェック/チェックされていない)
    export default function Home() {
    
        ...
        const updateToDo = async (todo) => {
                let newBody = { 
                   ...todo,
                   isCompleted: !todo.isCompleted
                };
                const resp = await fetch(`api/todos/${todo.key}`, 
                   {
                       method: 'put', 
                       body: JSON.stringify(newBody)
                   }
                );
    
                await getToDos();
            }
        ...
        return (
        ...
    
                <ToDo 
                    key={todo.key} 
                    content={`${index + 1}. ${todo.content}`} 
                    isCompleted={todo.isCompleted} 
                    onChange={() => updateToDo(todo)}
            />
        ...
        )
    }
    
    
    この関数はPUT 反対にpages/api/todos/[tid].js :
    import { Deta } from 'deta';
    
    const deta = Deta(process.env.DETA_PROJECT_KEY);
    
    const base = deta.Base('todos');
    
    export default async (req, res) => {
    
      let { body, method, query: { tid } } = req;
      let respBody = {};
    
      if (method === 'PUT') {
    
        body = JSON.parse(body);
        respBody = await base.put(body);
        res.statusCode = 200;
    
      } else if (method === 'DELETE') {
    
        // To Be Implemented
    
      }
    
      res.json(respBody);
    }
    
    このハンドラでは、body 当社のプットメソッドを介して当社のデータベースに行うに更新を格納します.ボディが含まれているのでkey これは正しく古いレコードを上書きします.

    Aを削除する


    最後に、doを削除するには、呼び出し元のAPI呼び出しを追加しましょうDELETE api/todos/{tid} ボタンクリックに基づきます
    export default function Home() {
    
      ...
    
    
      const deleteToDo = async (tid) => {
        const resp = fetch(`api/todos/${tid}`, {method: 'delete'});
        setTimeout(getToDos, 200);
      }
    
        ...
        return (
        ...
                    <ToDo 
                      key={todo.key} 
                      content={`${index + 1}. ${todo.content}`} 
                      isCompleted={todo.isCompleted} 
                      onChange={() => updateToDo(todo)}
                      onDelete={() => deleteToDo(todo.key)}
                    />  
        ...
        )
    
    }
    
    機能deleteToDo , 呼び出されると、DELETE リクエストpages/api/todos/{tid} , そのハンドラは以下のようになります.
    import { Deta } from 'deta';
    
    const deta = Deta(process.env.DETA_PROJECT_KEY);
    
    const base = deta.Base('todos');
    
    export default async (req, res) => {
    
      let { body, method, query: { tid } } = req;
      let respBody = {};
    
      if (method === 'PUT') {
    
      ...
    
      } else if (method === 'DELETE') {
    
        respBody = await base.delete(tid);
        res.statusCode = 200;
    
      }
    
      res.json(respBody);
    }
    
    このハンドラでは、delete method DETA SDKから.

    最後の事柄


    すべてのロジックがこの時点で実装されており、結果としてアプリケーションをVercelに展開できます.
    また、いくつかのクリックでそれを行うことができますDeta 「プロジェクト」キーをクリックし、下のボタンをクリックし、プロジェクトキーを環境変数として設定しますDETA_PROJECT_KEY --Vercelの流れの間.

    私たちはあなたが今表示することができますし、DTAベースのGUI、ガイドからDOSを管理することを忘れないでください.あなたがここからDOSにあなたの1つを加えるか、変更するならば、変化はページ・リフレッシュのVercelアプリでロードされます.


    言及する価値がある最後のものは、このアプリは、物事をシンプルに保つためにアプリケーションの状態を管理するための標準的なバニラ反応パターンを使用しています.しかし、パフォーマンスを向上させるために次のスマートなもの(USEWRのようなライブラリと並行して)を利用することができます.あなたがこのアプリを展開した場合は、Serverless関数が応答する300 msを取るように、作成、変更、削除の遅延に気づくでしょう.いくつかの改善と、我々はパフォーマンスを向上させることができますし、クライアント側で瞬時に応答感を作成します.ラウンド2のために調整滞在.