Cara membuat aplikasi obrolan dalam dua puluh menit

gambar



Ayah saya suka mengingatkan saya bahwa, sebagai insinyur komputer di tahun 1970-an, " dia adalah seorang programmer sebelum pemrograman menjadi mode ." Dia bahkan menunjukkan skrip Fortran dan COBOL lama beberapa kali. Setelah membaca kode ini, saya dengan yakin dapat mengatakan bahwa pemrograman pasti lebih keren hari ini .



Ciri khas bahasa pemrograman modern dan lingkungan pengembangan adalah seberapa sedikit kode yang harus ditulis oleh pengembang. Dengan menggunakan bahasa tingkat tinggi bersama dengan banyak API yang tersedia, paket sumber terbuka, dan layanan berbayar, aplikasi - bahkan yang memiliki persyaratan kompleks - dapat dibangun dengan cukup cepat.



Perbandingan untuk mendemonstrasikan evolusi pengembangan perangkat lunak adalah konstruksi. Suatu ketika, pembangunan rumah apa pun dimulai dengan menebang pohon di lokasi Anda. Akan tetapi, bahan, alat, dan metode dengan cepat muncul sehingga konstruksi lebih cepat selesai, objek menjadi lebih kuat, dan pekerja dibebaskan dari beberapa tugas dasar.



Berapa banyak gedung pencakar langit yang akan dibangun jika pembangun menambang baja mereka sendiri?



Pengembang perangkat lunak, yang terus bekerja hingga hari ini, di awal karir mereka "menebang pohon mereka sendiri". Pada saat yang sama, inovasi yang belum pernah terjadi sebelumnya pada dekade terakhir ini mengarah pada fakta bahwa industri perangkat lunak mulai berkembang dengan cara yang sama seperti konstruksi.



Sederhananya, pengembang modern sekarang memiliki alat, teknik, dan praktik terbaik untuk menyelesaikan proyek lebih cepat, mendapatkan aplikasi yang stabil, dan menyelamatkan pengembang dari tugas tingkat rendah.



Cara membuat aplikasi obrolan



Mari segera buat sesuatu yang biasanya membutuhkan waktu berhari-hari atau berminggu-minggu. Kami akan membuat aplikasi Ruang Obrolan Publik yang menggunakan WebSockets untuk perpesanan waktu nyata.



WebSockets secara bawaan didukung oleh semua browser modern. Namun, tujuan kami adalah menemukan alat apa yang dapat kami gunakan di tempat kerja, bukan menemukannya kembali . Dengan pemikiran ini, kami akan menggunakan teknologi berikut:



  • 8base β€Š- API GraphQL Terkelola
  • VueJSβ€Š - Kerangka JavaScript


Proyek awal dan file README lengkap dapat ditemukan di repositori GitHub ini . Jika Anda hanya ingin melihat aplikasi yang sudah selesai, lihat cabang ruang obrolan publik.



Selain itu, video di bawah ini (dalam bahasa Inggris) menjelaskan setiap langkah dengan lebih detail.



Ayo mulai.



Tujuh langkah membuat aplikasi obrolan:



1. Pengaturan proyek



Gandakan proyek awal dan buka direktori obrolan grup. Anda dapat memutuskan sendiri apakah akan menggunakan yarn atau npm untuk menginstal dependensi proyek. Bagaimanapun, kita membutuhkan semua paket NPM yang ditentukan dalam file package.json.



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


Untuk berinteraksi dengan GraphQL API, kita perlu menyiapkan tiga variabel lingkungan. Buat file .env.local di direktori root dengan perintah berikut, dan aplikasi Vue, setelah inisialisasi, akan secara otomatis mengatur variabel lingkungan yang kami tambahkan ke file ini. Kedua nilai dan tidak boleh diubah. Anda hanya perlu menyetel nilainya . Jika Anda memiliki ruang kerja 8base yang ingin Anda gunakan untuk membuat aplikasi obrolan menggunakan tutorial kami, perbarui file .env.local dengan ID ruang kerja Anda. Jika tidak, dapatkan ID ruang kerja dengan mengikuti langkah 1 dan 2 dari Panduan Memulai Cepat 8base .



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. Skema impor



Sekarang kita perlu menyiapkan sisi server. Di root repositori ini, Anda harus menemukan file tersebut chat-schema.json. Untuk mengimpornya ke ruang kerja, Anda hanya perlu menginstal baris perintah 8base dan login, lalu mengimpor file skema.



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


3. Akses API



Tugas terakhir untuk backend adalah mengizinkan akses publik ke API GraphQL.



Di konsol 8base masuk ke App Services > Roles > Guest. Perbarui perizinan yang ditetapkan untuk posting dan pengguna sehingga mereka dicentang atau ditetapkan sebagai Semua Catatan (seperti yang ditunjukkan pada gambar di bawah).



Peran Tamu menentukan apa yang boleh dilakukan oleh pengguna yang membuat permintaan API yang tidak diautentikasi.



gambar

Editor peran di konsol 8base.



4. Menulis query GraphQL



Pada langkah ini, kita akan mendefinisikan dan menulis semua query GraphQL yang kita perlukan untuk komponen chat kita. Ini akan membantu kami memahami data apa yang akan kami baca, buat, dan dengarkan (melalui WebSockets) menggunakan API.



Kode berikut harus ditempatkan dalam sebuah file src / utils / graphql.js. Baca komentar di atas setiap konstanta yang diekspor untuk memahami apa yang dilakukan setiap kueri.




/* 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. Konfigurasi klien Apollo untuk langganan



Dengan kueri GraphQL kami tertulis, saatnya menyiapkan modul API kami.



Pertama, mari kita tangani klien API ApolloClientdengan default yang diperlukan. Bagi createHttpLinkkami, kami menyediakan titik akhir ruang kerja yang sepenuhnya terbentuk. Kode ini ada di 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,    .


Kemudian kami akan menangani klien langganan menggunakan subscriptions-transport-wsdan isomorphic-ws. Kode ini sedikit lebih panjang dari yang sebelumnya, jadi ada baiknya meluangkan waktu untuk membaca komentar di kode.



Kami menginisialisasi SubscriptionClientmenggunakan titik akhir WebSockets dan workspaceIddalam parameter connectionParams. Kami kemudian menggunakan ini subscriptionClientdalam dua metode yang ditentukan dalam ekspor default: subscribe()dan close().



subscribememungkinkan kita membuat langganan baru dengan data dan panggilan balik kesalahan. Metode close inilah yang bisa kita gunakan untuk menutup koneksi saat kita keluar dari chat.



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. Menulis Komponen Vue



Kami sekarang memiliki semua yang kami butuhkan untuk membuat obrolan publik. Hanya tinggal satu komponen tersisa untuk ditulis GroupChat.vue.



Muat komponen dengan menggunakan benang melayani dan mari kita lanjutkan.



Catatan penting: setiap orang memiliki ide kecantikannya sendiri, jadi saya hanya membuat gaya minimal yang diperlukan agar komponen berfungsi.



Skrip komponen



Pertama, kita perlu mengimpor modul, gaya sederhana, dan kueri GraphQL kami. Semua ini ada di tangan kita src / utils.

Deklarasikan impor berikut dalam 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";


Data komponen



Kita dapat menentukan properti data mana yang ingin kita gunakan dalam fungsi data komponen kita. Yang kita butuhkan hanyalah cara untuk menyimpan pengguna obrolan, pesan, nama pengguna "saat ini", dan pesan apa pun yang belum terkirim. Properti ini dapat ditambahkan sebagai berikut:



/* imports ... */

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


Pengait siklus hidup



Pengait siklus hidup kami berjalan di berbagai titik dalam masa pakai komponen Vue. Misalnya saat dipasang atau diperbarui. Dalam hal ini, kami hanya tertarik pada kreasi dan beforeDestroykomponen. Dalam kasus seperti itu, kami ingin membuka langganan obrolan atau menutupnya.



/* ... */

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();
},
};


Metode komponen



Kita perlu menambahkan beberapa metode untuk memproses setiap respon call / API ( createMessage, addMessage, closeChat, dll). Semuanya akan disimpan di objek metode komponen kita.

Perlu

dicatat satu hal: kebanyakan mutasi tidak menunggu dan tidak menangani jawabannya. Ini karena kami memiliki langganan yang melacak mutasi ini. Setelah peluncuran yang sukses, data acara diproses oleh langganan.

Sebagian

besar metode ini berbicara sendiri. Oya, baca komentar di kode berikut.



/*  ... */

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: '' } }
  }
},
‍
/*  ... */
}


Template komponen



Last but not least, kami memiliki komponen GroupChat.vue.

Ada

ribuan tutorial bagus tentang cara membuat antarmuka pengguna yang cantik. Ini bukan salah satunya. Pola

berikut

Untuk membuatnya cantik atau tidak, itu terserah Anda. Karena itu, mari kita segera membahas markup kunci yang telah kami terapkan di sini.

Seperti

biasa, baca komentar sebaris ke kode.



<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>


Dan sekarang obrolan publik dibangun. Jika Anda membukanya di jaringan lokal, Anda dapat mulai mengirim dan menerima pesan. Namun, untuk membuktikan bahwa ini adalah obrolan grup yang nyata, buka beberapa jendela dan lihat perkembangan percakapan.



7. Kesimpulan dan pengujian



Dalam tutorial ini, kita telah menjelajahi bagaimana menggunakan alat pengembangan modern memungkinkan kita membuat aplikasi dunia nyata dalam hitungan menit.



Saya harap Anda juga belajar cara menginisialisasi ApolloClientdan SubscriptionClientmengeksekusi kueri GraphQL, mutasi dan langganan secara efisien di ruang kerja 8base, serta sedikit tentang VueJS.



Baik Anda sedang mengerjakan game seluler, messenger, aplikasi notifikasi, atau proyek lain yang membutuhkan data waktu nyata, langganan adalah alat yang hebat. Dan sekarang kami baru saja mulai mempertimbangkannya.



Buat aplikasi obrolan dengan 8base



8base adalah backend tanpa server turnkey sebagai layanan yang dibangun oleh pengembang untuk pengembang. Platform 8base memungkinkan pengembang untuk membangun aplikasi cloud yang menakjubkan menggunakan JavaScript dan GraphQL. Pelajari lebih lanjut tentang platform 8base di sini .



All Articles