20分でチャットアプリを作成する方法

画像



私の父は、1970年代のコンピューターエンジニアとして、「プログラミングが流行する前はプログラマーだった」ことを思い出させてくれます。彼は古いFortranおよびCOBOLスクリプトを数回示しました。このコードを読んだ後、今日のプログラミングは間違いなくクールだと自信を持って言えます



最新のプログラミング言語と開発環境の特徴は、開発者が作成する必要のあるコードがどれだけ少ないかです。利用可能な多くのAPI、オープンソースパッケージ、有料サービスに加えて高レベルの言語を使用することで、複雑な要件を持つアプリケーションでも、非常に迅速に構築できます。



ソフトウェア開発の進化を実証するための比較は、構築です。昔々、家の建設はあなたの場所で木を切り倒すことから始まりました。しかし、材料、ツール、方法がすぐに登場したため、建設がより早く完了し、オブジェクトがより強くなり、労働者はいくつかの基本的な作業から解放されました。



ビルダーが自分の鋼を採掘した場合、いくつの超高層ビルが建設されますか?



今日まで働き続けているソフトウェア開発者は、キャリアの黎明期に「自分たちの木を切る」。同時に、過去10年間の前例のない革新により、ソフトウェア業界は建設とほぼ同じ方法で発展し始めたという事実につながりました。



簡単に言えば、今日の開発者は、プロジェクトをより速く完了し、安定したアプリケーションを取得し、開発者を低レベルのタスクから救うためのツール、テクニック、およびベストプラクティスを手に入れました。



チャットアプリの作り方



数日から数週間かかっていたものをすばやく作成しましょう。リアルタイムメッセージングにWebSocketを使用するパブリックチャットルームアプリケーションを作成します。



WebSocketは、最新のすべてのブラウザーでネイティブにサポートされています。ただし、私たちの目標は、仕事で使用できるツールを見つけることであり、それらを再発明することではありませんこれを念頭に置いて、次のテクノロジーを使用します。



  • 8base- マネージドGraphQLAPI
  • VueJS  -JavaScriptフレームワーク


スタータープロジェクトと完全なREADMEファイルは、このGitHubリポジトリにあります完成したアプリケーションのみを確認したい場合は、public-chat-roomブランチをご覧ください。



さらに、以下のビデオ(英語)では、各ステップについて詳しく説明しています。



はじめましょう。



チャットアプリケーションを作成するための7つのステップ:



1.プロジェクトの設定



スタータープロジェクトのクローンを作成し、グループチャットディレクトリに移動します。プロジェクトの依存関係をインストールするためにyarnとnpmのどちらを使用するかを自分で決めることができます。いずれの場合も、package.jsonファイルで指定されているすべてのNPMパッケージが必要です。



#  
git clone https://github.com/8base/Chat-application-using-GraphQL-Subscriptions-and-Vue.git group-chat
#   
cd group-chat
#  
yarn


GraphQL APIを操作するには、3つの環境変数を設定する必要があります。次のコマンドを使用してルートディレクトリに.env.localファイルを作成すると、Vueアプリケーションは、初期化後に、このファイルに追加した環境変数を自動的に設定します。 両方の値とは変更しないでください。値を設定するだけです チュートリアルを使用してチャットアプリケーションを作成するために使用する8baseワークスペースがある場合は、.env.localファイルをワークスペースIDで更新します。そうでない場合は、8baseクイックスタートの手順1と2に従ってワークスペースIDを取得します



echo 'VUE_APP_8BASE_WORKSPACE_ID=<YOUR_8BASE_WORKSPACE_ID>

VUE_APP_8BASE_API_ENDPOINT=https://api.8base.com

VUE_APP_8BASE_WS_ENDPOINT=wss://ws.8base.com' \

> .env.local




VUE_APP_8BASE_API_ENDPOINTVUE_APP_8BASE_WS_ENDPOINTVUE_APP_8BASE_WORKSPACE_ID







2.スキーマをインポートします



次に、サーバー側を準備する必要があります。このリポジトリのルートに、ファイルがありますchat-schema.jsonワークスペースにインポートするには、8baseコマンドラインをインストールしてログインし、スキーマファイルをインポートするだけです。



#  8base CLI
yarn global add 8base-cli
#  CLI
8base login
#      
8base import -f chat-schema.json -w <YOUR_8BASE_WORKSPACE_ID>


3.APIアクセス



バックエンドの最後のタスクは、GraphQLAPIへのパブリックアクセスを許可することです。



8baseコンソールでに移動しApp Services > Roles > Guestます。投稿とユーザーの両方に設定されている権限を更新して、チェックするか、すべてのレコードとして設定します(下のスクリーンショットを参照)。



ゲストロールは、認証されていないAPIリクエストを行うユーザーに許可されることを決定します。



画像

8baseコンソールのロールエディター。



4.GraphQLクエリの記述



このステップでは、チャットコンポーネントに必要なすべてのGraphQLクエリを定義して書き出します。これは、APIを使用して(WebSocketを介して)読み取り、作成、およびリッスンするデータを理解するのに役立ちます。



次のコードをファイルに配置する必要がありますsrc / utils / graphql.jsエクスポートされた各定数の上のコメントを読んで、各クエリの機能を理解してください。




/* gql      graphQL */
import gql from "graphql-tag";
/* 1.    -   10  */
export const InitialChatData = gql`
{
  usersList {
    items {
      id
      email
    }
  }
  messagesList(last: 10) {
    items {
      content
      createdAt
      author {
        id
        email
      }
    }
  }
}
`;
/* 2.          */
export const CreateUser = gql`
mutation($email: String!) {
  userCreate(data: { email: $email, roles: { connect: { name: "Guest" } } }) {
    id
  }
}
`;
/* 3.   */
export const DeleteUser = gql`
mutation($id: ID!) {
  userDelete(data: { id: $id, force: true }) {
    success
  }
}
`;
/* 4.        */
export const UsersSubscription = gql`
subscription {
  Users(filter: { mutation_in: [create, delete] }) {
    mutation
    node {
      id
      email
    }
  }
}
`;
/* 5.          */
export const CreateMessage = gql`
mutation($id: ID!, $content: String!) {
  messageCreate(
    data: { content: $content, author: { connect: { id: $id } } }
  ) {
    id
  }
}
`;
/* 6.     . */
export const MessagesSubscription = gql`
subscription {
  Messages(filter: { mutation_in: create }) {
    node {
      content
      createdAt
      author {
        id
        email
      }
    }
  }
}
`;




5.サブスクリプション用のApolloクライアントの構成



GraphQLクエリを作成したら、APIモジュールを設定します。



まず、ApolloClient必要なデフォルトを使用してAPIクライアントに取り組みましょう以下のためにcreateHttpLink私たち私たちは完全に形成されたワークスペースのエンドポイントを提供します。このコードはにありsrc/utils/api.jsます。



import { ApolloClient } from "apollo-boost";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
const { VUE_APP_8BASE_API_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;

export default new ApolloClient({
link: createHttpLink({
  uri: `${VUE_APP_8BASE_API_ENDPOINT}/${VUE_APP_8BASE_WORKSPACE_ID}`,
}),
cache: new InMemoryCache(),
});

// Note:     ,    // ApolloClient,    .


その後、我々は、使用してサブスクリプションクライアントに対処しますsubscriptions-transport-wsisomorphic-wsこのコードは前のコードより少し長いので、時間をかけてコードのコメントを読む価値があります。WebSocketsエンドポイントとパラメーターを使用して



初期化SubscriptionClientworkspaceIdますconnectionParams次に、これをsubscriptionClientデフォルトのエクスポートで定義されている2つの方法で使用します:subscribe()close()



subscribeデータとエラーコールバックを使用して新しいサブスクリプションを作成できます。closeメソッドは、チャットを終了するときに接続を閉じるために使用できる方法です。



import WebSocket from "isomorphic-ws";
import { SubscriptionClient } from "subscriptions-transport-ws";
const { VUE_APP_8BASE_WS_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;

/**
*   ,  
*     .
*/

const subscriptionClient = new SubscriptionClient(
VUE_APP_8BASE_WS_ENDPOINT,
{
  reconnect: true,
  connectionParams: {
    /**
      * Workspace ID    ,  
*  Websocket  
*    
      */
    workspaceId: VUE_APP_8BASE_WORKSPACE_ID,
  },
},
/**
  *    WebSocket,   W3C. * ,        *WebSocket (,   NodeJS)
  */
WebSocket
);
export default {
/**
  *   ,      *'data’  'error’
  */
subscribe: (query, options) => {
  const { variables, data, error } = options;
  /**
    *     .
    */
  const result = subscriptionClient.request({
    query,
    variables,
  });
  /**
    *       * ,     , 
* subscriptionClient
    */
  const { unsubscribe } = result.subscribe({
    /**
      *       
* ,  .
      */
    next(result) {
      if (typeof data === "function") {
        data(result);
      }
    },
    /**
      *          ,  .
      */
    error(e) {
      if (typeof error === "function") {
        error(e);
      }
    },
  });
  return unsubscribe;
},
/**
  *  subscriptionClient .
  */
close: () => {
  subscriptionClient.close();
},
};
// .     SubscriptionClient   , 
// ,    .


6.Vueコンポーネントの作成



これで、公開チャットを作成するために必要なものがすべて揃いました。書き込むコンポーネントは1つだけGroupChat.vueです。



ヤーンサーブを使用してコンポーネントをロードし、続行しましょう。



重要な注意:誰もが美しさについて独自の考えを持っているので、コンポーネントが機能するために必要な最小限のスタイルのみを作成しました。



コンポーネントスクリプト



まず、モジュール、シンプルなスタイル、GraphQLクエリをインポートする必要があります。これはすべて私たちのもの src / utilsです。

で次のインポートを宣言しますGroupChat.vue



/* API  */
import Api from "./utils/api";
import Wss from "./utils/wss";

/* graphQL  */
import {
InitialChatData,
CreateUser,
DeleteUser,
UsersSubscription,
CreateMessage,
MessagesSubscription,
} from "./utils/graphql";
/*  */
import "../assets/styles.css";


コンポーネントデータ



コンポーネントのデータ関数で使用するデータプロパティを定義できます。必要なのは、チャットユーザー、メッセージ、「現在の」ユーザーの名前、およびまだ送信されていないメッセージを保存する方法だけです。これらのプロパティは、次のように追加できます。



/* imports ... */

export default {
name: "GroupChat",
data: () => ({
  messages: [],
  newMessage: "",
  me: { email: "" },
  users: [],
}),
};


ライフサイクルフック



私たちのライフサイクルフックは、Vueコンポーネントの寿命のさまざまな時点で実行されます。たとえば、マウントまたは更新されたとき。この場合、作成とbeforeDestroyコンポーネントのみに関心があります。このような場合、チャットサブスクリプションを開くか、閉じます。



/* ... */

export default {
/*   ... */

/**
  *   ,    .
  */
created() {
  /**
    *   ,       
    */
  Wss.subscribe(UsersSubscription, {
    data: this.handleUser,
  });
  /**
    *   ,     
    */
  Wss.subscribe(MessagesSubscription, {
    data: this.addMessage,
  });
  /**
    *     (   10 )
    */
  Api.query({
    query: InitialChatData,
  }).then(({ data }) => {
    this.users = data.usersList.items;
    this.messages = data.messagesList.items;
  });
  /**
    *     ,   
    */
  window.onbeforeunload = this.closeChat;
},
/**
  *   ,    .
  */
beforeDestroy() {
  this.closeChat();
},
};


コンポーネントメソッド



私たちは、それぞれの呼び出し/ APIレスポンスを処理するためにいくつかのメソッドを追加する必要があります(createMessageaddMessagecloseChat、など)。それらはすべて、コンポーネントのメソッドオブジェクトに格納されます。 1つのこと

する必要が

これは、これらの変異を追跡するサブスクリプションがあるためです。起動が成功すると、イベントデータはサブスクリプションによって処理されます。 これらの方法の

ほとんど

とにかく、次のコードのコメントを読んでください。



/*  ... */

export default {
/*   ... */
methods: {
  /**
    *   ,     .
    */
  createUser() {
    Api.mutate({
      mutation: CreateUser,
      variables: {
        email: this.me.email,
      },
    });
  },
  /**
    *     ID.
    */
  deleteUser() {
    Api.mutate({
      mutation: DeleteUser,
      variables: { id: this.me.id },
    });
  },
  /**
    *        ,   
*           
* .
*
*    ,      ,  
*   ,   .
    */
  handleUser({
    data: {
      Users: { mutation, node },
    },
  }) {
    ({
      create: this.addUser,
      delete: this.removeUser,
    }[mutation](node));
  },
  /**
    *      users,  , *     .
    */
  addUser(user) {
    if (this.me.email === user.email) {
      this.me = user;
    }
    this.users.push(user);
  },
  /**
    *     users  ID.
    */
  removeUser(user) {
    this.users = this.users.filter(
      (p) => p.id != user.id
    );
  },
  /*    */
  createMessage() {
    Api.mutate({
      mutation: CreateMessage,
      variables: {
        id: this.me.id,
        content: this.newMessage,
      },
    }).then(() => (this.newMessage = ""));
  },
  /**
    *        .  * ,    ,       *.
    */
  addMessage({
    data: {
      Messages: { node },
    },
  }) {
    this.messages.push(node);
  },
  /**
    *        .          beforeDestroy     .
    */
  closeChat () {
    /*     */
    Wss.close()
    /*   */
    this.deleteUser();
    /*     */
    this.me = { me: { email: '' } }
  }
},
/*  ... */
}


コンポーネントテンプレート



最後になりましたが、コンポーネントがありますGroupChat.vue 美しいユーザーインターフェイスを作成する方法について

がありは、

これはそれらの1つではありません。

次の

パターンは、チャットアプリケーションの最小要件に一致します。それを美しくするかどうかはあなた次第です。そうは言っても、ここで実装した主要なマークアップについて簡単に見ていきましょう。 常に、コードにインラインコメントを読んで。







<template>
<div id="app">
  <!--
           ,     .      ..
    -->
  <div v-if="me.id" class="chat">
    <div class="header">
      <!--
           ,      ,  ,     ,   .
        -->
      {{ users.length }} Online Users
      <!--
           ,   closeChat..
        -->
      <button @click="closeChat">Leave Chat</button>
    </div>
    <!--
     ,      ,      div.  ,         ,     me.
      -->
    <div
      :key="index"
      v-for="(msg, index) in messages"
      :class="['msg', { me: msg.participant.id === me.id }]"
    >
      <p>{{ msg.content }}</p>
      <small
        ><strong>{{ msg.participant.email }}</strong> {{ msg.createdAt
        }}</small
      >
    </div>
    <!--
      newMessage.
      -->
    <div class="input">
      <input
        type="text"
        placeholder="Say something..."
        v-model="newMessage"
      />
      <!--
           ,    createMessage.
        -->
      <button @click="createMessage">Send</button>
    </div>
  </div>
  <!--
          .     ,   createUser.
    -->
  <div v-else class="signup">
    <label for="email">Sign up to chat!</label>
    <br />
    <input
      type="text"
      v-model="me.email"
      placeholder="What's your email?"
      @blur="createUser"
      required
    />
  </div>
</div>
</template>


そして今、パブリックチャットが構築されています。ローカルネットワークで開くと、メッセージの送受信を開始できます。ただし、これが実際のグループチャットであ​​ることを証明するには、複数のウィンドウを開いて会話の進行状況を確認します。



7.結論とテスト



このチュートリアルでは、最新の開発ツールを使用して、実際のアプリケーションを数分で作成する方法について説明しました。



また、GraphQLクエリ、ミューテーション、サブスクリプションを8baseワークスペースで効率的に初期化ApolloClientしてSubscriptionClient実行する方法と、VueJSについて少し学んだことを願っています



モバイルゲーム、メッセンジャー、通知アプリ、またはリアルタイムデータを必要とするその他のプロジェクトに取り組んでいるかどうかにかかわらず、サブスクリプションは優れたツールです。そして今、私たちはそれらを検討し始めたところです。



8baseでチャットアプリを作成する



8baseは、開発者が開発者向けに構築したサービスとしてのターンキーサーバーレスバックエンドです。8baseプラットフォームにより、開発者はJavaScriptとGraphQLを使用して見事なクラウドアプリケーションを構築できます。8baseプラットフォームの詳細については、こちらをご覧ください



All Articles