コンテンツへスキップ

NEW  近日公開:フリートに質問すると答えが返ってくる — AIのためのMCPサーバー。  詳細を見る →

ブログ

GraphQL を活用したリモートデバイスへのアクセスと監視

· 約21分で読了 · 著者: Wava Jacobson
GraphQL を使ったリモートデバイスへのアクセスと監視

はじめに

Remote.Itを既に使ったことがあれば、Remote.Itがダッシュボードを提供し、デバイス、その状態を確認したり、接続したりできることをご存知でしょう。しかし、特定のものを監視する必要がある場合はどうしたらよいでしょうか?

例えば、Remote.Itはアカウントキーの認証情報を使用してデバイスに関するデータにアクセスするために使用できるAPIを提供しています。

この記事では、GraphQL APIを活用して、リモートデバイスとイベントを監視するための小さなReactアプリを構築する方法を学びます。

Remote.It GraphQL API

実は、Remote.ItはREST APIとGraphQL APIの両方を提供しています。

ですから、コーディングに入る前に、RESTとGraphQLの主な違いについて説明しましょう。これは私たちの選択を正当化するのに役立つでしょう。

構成

RESTは6つのアーキテクチャ上の制約に準拠しています:

  • 統一されたインターフェース。
  • クライアント・サーバー。
  • ステートレス。
  • キャッシュ可能。
  • レイヤード・システム。
  • コード・オン・デマンド(オプション)

ただし、GraphQLはデータの形状を記述するスキーマとタイプシステムに組織され、GraphQLアプリケーションで使用できるさまざまなデータ型を定義するのに役立ちます。

形式

RESTはXML、JSON、HTML、プレーンテキストなど多くの形式をサポートしています。GraphQLはJSONのみをサポートしています。

データの取得

REST APIを使用してデータを取得するには、GET、POST、PUT、PATCH、またはDELETEを使用できます。GraphQLでは、Query(データを取得する)またはmutations(オブジェクトを作成、削除、または変更する)のタイプでPOSTリクエストを行うだけです。

以上がRESTとGraphQLの主な違いです。

コーディングに入りましょう。

シンプルなReactプロジェクト

まず、React Appプロジェクトを作成しましょう。

yarn create react-app remoteit-react-graphql

プロジェクトのインストールが完了したら、axios、bootstrap、swr、axios-auth-refreshを追加します。

yarn add axios swr axios-auth-refresh react-bootstrap@next bootstrap@5.1.1 react-router-dom

WebページのスタイリングにはBootstrapを、APIへのリクエストにはaxiosを使用します。

axios-auth-refreshは、リクエストに使用されている現在のトークンが期限切れの場合、新しいトークンを取得するために使用されます。

1 - APIキーを使用した認証

RESTおよびGraphQL APIへのリクエストを行う前に、開発者APIキーを使用する必要があります。

このAPIキーは、欲しいデータを取得するためにトークンと共に各リクエストで送信されます。

キーにアクセスするには、https://app.remote.it/のウェブポータルのアカウントセクションに移動してください。

完了したら、プロジェクトディレクトリに.envファイルを作成します。このファイルは、開発者APIキーやAPI URLなどの機密情報を格納するために使用します。

REACT_APP_API_URL=https://api.remote.it REACT_APP_DEV_API_KEY=YOUR DEVELOPER API KEY

それでは、axiosを使って独自のフェッチャーを作成しましょう。なぜ今作成するのでしょうか?期限切れのトークンを使ってリクエストを行うため、このトークンが期限切れになった場合に新しいトークンを取得するのが役立ちます。インターセプターを記述することになります。

srcディレクトリに、axios.jsというファイルを作成します。

import axios from “axios”; import createAuthRefreshInterceptor from “axios-auth-refresh”; import {useHistory} from “react-router-dom”;

const axiosService = axios.create({ baseURL: process.env.REACT_APP_API_URL, headers: { ‘Content-Type’: ‘application/json’, ‘apikey’: process.env.REACT_APP_DEV_API_KEY } });

axiosService.interceptors.request.use(async (config) => { const token = localStorage.getItem(‘token’);

if (token){ config.headers.token = token; console.debug(‘[Request]’, config.baseURL + config.url, JSON.stringify(token)); }

return config; })

axiosService.interceptors.response.use( (res) => { console.debug(‘[Response]’, res.config.baseURL + res.config.url, res.status, res.data); return Promise.resolve(res); }, (err) => { console.debug( ‘[Response]’, err.config.baseURL + err.config.url, err.response.status, err.response.data ); return Promise.reject(err); } );

const refreshAuthLogic = async (failedRequest) => { const authHash = localStorage.getItem(‘authHash’) const username = localStorage.getItem(‘username’);

const history = useHistory(); if (authHash) { return axios .post( ‘/apv/v27/user/login’, { username: username, authhash: authHash }, { baseURL: process.env.REACT_APP_API_URL } ) .then((resp) => { const { token, service_authhash } = resp.data; failedRequest.response.config.headers.token = token; localStorage.setItem(“authHash”, service_authhash); localStorage.setItem(‘token’, token); }) .catch((err) => { if (err.response && err.response.status === 401){ history.push(‘/login’); } }); } };

createAuthRefreshInterceptor(axiosService, refreshAuthLogic);

export function fetcher(url, data) { return axiosService.post(url, data).then((res) => res.data); }

export default axiosService;

完了したら、ログインページを作成できます。

ログイン

ログインページでは、ユーザー名とパスワードを入力できます。リクエストが成功した場合、ダッシュボードページにリダイレクトされます。

import React, {useState} from “react”; import axios from “axios”; import {useHistory} from “react-router-dom”;

const Login = (key, value) => {

const history = useHistory(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState("");

function handleSubmit(event) { event.preventDefault(); axios.post(${process.env.REACT_APP_API_URL}/apv/v27/user/login, { username: email, password: password }, { headers: { “Content-Type”: “application/json”, “apikey”: process.env.REACT_APP_DEV_API_KEY } }).then( r => { localStorage.setItem(“username”, email); localStorage.setItem(“authHash”, r.data.service_authhash); localStorage.setItem(‘token’, r.data.token) history.push(‘/home’) }).catch(e => { setError(e.response.data.reason); })

}

return (

setEmail(e.target.value)} />
Password setPassword(e.target.value)} />

export default Login;

ご覧のとおり、リクエストが成功すると、トークンとservice_authhashがlocal storageに登録されます。service_authhashは再度ログインして新しいトークンを取得するために使用されます。

使用方法

ログインページの準備ができました。プロジェクトにreact-routerを統合し、ルートの定義を開始する時が来ました。

import { BrowserRouter as Router, Switch, Route, } from “react-router-dom”; import Login from ”./Login”; import Home from ”./Home”; import “bootstrap/dist/css/bootstrap.min.css”; function App() { return (

); }

export default App;

ホームページを追加しましょう。

デバイスと最新のイベントログを表示する

ホームページには2つのテーブルが含まれます。1つはデバイスを表示し、もう1つは最後のイベントを表示します。

GraphQL APIでクエリを実行します。

ですから、まず使用するクエリを記述しましょう。

import React from “react”; import useSWR from ‘swr’ import {fetcher} from ”./axios”;

const devicesQuery = { query: { login { email devices(size: 1000, from: 0) { total hasMore items { id name hardwareId created state endpoint{geo{latitude longitude}} } } } } }

const eventsQuery = { query: { login { events { hasMore total items { type owner { email } actor { email } target { created id name } users { email } timestamp } } } } }

クエリについて簡単に説明しましょう。一般的に、両方のクエリが以下を持つことに気付くことができます:

  • login: クエリが認証を必要とし、ユーザーのメールアドレスを返すことを意味します。
  • sizeなどのパラメータを持つアイテム(デバイス/イベント)。任意のフィルターを適用することもできます。
  • totalはアイテムの総数を示し、取得されていない残りの数があります。

コンポーネントのロジックを書き始めることができます。

ただし、まず、SWRとaxios.jsファイルに記述したフェッチャーを使用してリクエストを行いましょう。

SWRはデータ取得用のReactフックです。データキャッシングと定期的な再検証を可能にします。ダッシュボードが定期的に更新されるようにしたい場合に非常に便利です。

const Home = () => {

const dataDevices = useSWR(‘devices’, () => fetcher(‘/graphql/v1’, devicesQuery));

const dataEvents = useSWR(‘events’, () => fetcher(‘/graphql/v1’, eventsQuery));

return

}

そして最後にテンプレート化です。ダッシュボードとテーブルのUIを作成しましょう。

return (

Number of devices: {dataDevices.data?.data?.login?.devices?.total} { dataDevices.data?.data?.login?.devices?.items.map((device, index) => { console.log(device); return } ) }
Device id Name hardwareId Created State Geo localisation
{device.id} {device.name} {device.hardwareId} {formatDate(device.created)} {device.state} See localisation

Number of events: {dataEvents.data?.data?.login?.events?.total} { dataEvents.data?.data?.login?.events?.items?.map((event, index) => ( )) }
Type Owner Actor Target Name Time
{event.type} {event.owner?.email} {event.actor?.email} {event.target?.map((target, index) => (

{target.name} |

))}
{event.timestamp}
)

ダッシュボードはこのようになるはずです。

以上です。これがRemote.It GraphQL APIを使用してデバイスのイベントとステータスを監視する方法です。

APIはデバイスの状態とイベントを取得するだけでなく、より多くの機能を提供します。

また、以下のこともできます:

  • Remote.Itから通知を受け取るためのwebhookを作成する
  • デバイスへの接続を開始または停止する
  • アクセスキーを直接管理する。

また、これらのリクエストはすべてRESTで行うことができることも忘れてはいけません。これらについては、こちらのドキュメントをご覧ください。

結論

Remote.It APIを使い始めるには、こちらのドキュメントをご覧ください。Remote.It APIを使用してどんな魅力的なインテグレーションを構築するか、ぜひ見てみたいです。

このガイドのコードを見つけたい場合は、こちらのGitHubをご覧ください。

← すべての記事 更新日: 2023年11月10日
記事を検索