- 投稿日:2020-07-07T23:41:07+09:00
ざっくり Apollo
Apollo のチュートリアルをやったので、そこから分かったことをざっくりまとめ
時間がある人は Apollo がとても丁寧にチュートリアルを作ってるので、実際に手を動かしてやるととても理解が深まります
https://www.apollographql.com/docs/tutorial/introduction/動機
GraphQL とはなんぞやということが知りたかった
概要
サーバーサイドでやること
GraphQL ではまず下記の三つを定義
スキーマ
(js のオブジェクト go の構造体みたいなの)Query
(REST で言うとこの GET のメソッドたち)Mutation
(REST で言うとこの POST, PUT, DELETE のメソッドたち)DB(データソース)へのコネクトの conf 書いて
Resolver
(GET でどんな処理をするかとか POST でどんな処理するかとか)を定義するクライアントサイドでやること
Apollo Client を使って GrapQL をかく
(他にもクライアントサイドでの state の管理とかできるけど今回は割愛)詳細
サーバーサイド
※チュートリアルで使ってた ApolloServer(すなわち node)前提
まず GraphQL で扱うスキーマを定義
const { gql } = require("apollo-server"); const typeDefs = gql` type Anime { id: ID! title: String charactor: [Charactor] } type Charactor { id: ID! name: String age: String description: String } `;Query(REST でいうところの GET を定義)
type Query
の中に GET のメソッド書く感じconst typeDefs = gql` # ↑のコードの続き type Query { animes: [Anime] anime(id: ID!): Anime } `;Mutation(REST でいうところの POST PUT DELETE を定義)
type Mutation
の中にメソッド書く感じ
今回は Anime を delete するメソッドと Anime の title を更新するメソッドを追加const typeDefs = gql` # ↑のコードの続き # mutation実行時用のschemaを作る type AnimeUpdateResponse { success: Boolean! message: String anime: [Anime] } type Mutation { deleteAnime(animeId: ID!): AnimeUpdateResponse updateTitle(animeId: ID!, title: string!): AnimeUpdateResponse } `;Query の resolver の定義
今回の場合、Query で定義した animes と anime メソッドの処理内容
module.exports = { Query: { animes: async (_, __, { dataSources }) => await dataSources.animeAPI.getAllAnimes(), anime: async (_, { id }, { dataSources }) => await dataSources.animeAPI.getAnimeById({ animeId: id }), }, };
dataSources.animeAPI
が DB とのやり取りする adapter 的な感じこんな graphql がかけるようになる
GetAnimes は任意のクエリ名。query GetAnimes { animes() { id title charactor { name description } } }これはこんな感じのレスポンスを返してくれる
(イメージです。現実には違うかもしれません){ "data": { "animes": { "anime": [ { "id": "1", "charactor": [ { "name": "高須 竜児", "description": "目つきが悪い。家事がうまい。" }, { "name": "逢坂 大河", "description": "元祖ツンデレ" } ] } ] } } }必要なカラムだけ指定すれば良きなの、とても便利ですよねぇ
Mutation の resolver の定義
今回の場合、anime の update と delete
面倒なので delete のみmodule.exports = { // Query: { // ... // }, Mutation: { deleteAnime: async (_, { id }, { dataSources }) => { const result = await dataSources.animeAPI.delete({ id }); // AnimeUpdateResponseに合わせる if (!result) return { success: false, message: "faild delete anime", }; const animes = await dataSources.animeAPI.getAllAnimes(); return { success: true, message: "success delete anime", animes, }; }, }, };こんな graphql がかける
query DeleteAnimes { deleteAnime(id: 1) { success message animes { id } } }apollo server の起動
const { ApolloServer } = require("apollo-server"); const typeDefs = require("./schema"); const { createStore } = require("./utils"); const resolvers = require("./resolvers"); // DBのコネクト const store = createStore(); // DBのadapter的な const AnimeAPI = require("./datasources/anime"); const server = new ApolloServer({ typeDefs, resolvers, dataSources: () => ({ animeAPI: new AnimeAPI({ store }), }), }); server.listen().then(({ url }) => { console.log(`? Server ready at ${url}`); });クライアントサイド
チュートリアルが React なので React で
ApolloClient の import
ApolloClient は ApolloProvider に渡す
import { ApolloClient } from "apollo-client"; import { InMemoryCache, NormalizedCacheObject } from "apollo-cache-inmemory"; import { HttpLink } from "apollo-link-http"; import { ApolloProvider } from "@apollo/react-hooks"; import React from "react"; import ReactDOM from "react-dom"; import Pages from "./pages"; const cache = new InMemoryCache(); const link = new HttpLink({ uri: "http://localhost:4000/", }); const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({ cache, link, }); ReactDOM.render( <ApolloProvider client={client}> <Pages /> </ApolloProvider>, document.getElementById("root") );GraphQL の実行
hooks(useQuery, useMutation) を使って grapql 実行する
import React from "react"; import { useQuery } from "@apollo/react-hooks"; import gql from "graphql-tag"; export const GET_ANIMES = gql` query GetAnimes { animes() { id title charactor { name description } } } `; export const Animes: React.FC = () => { // GET_ANIMESで定義したqueryを実行する // <GetAnimes>はdataの型(apolloで自動生成される) const { data } = useQuery<GetAnimes>(GET_ANIMES); return ( <Div> {data.animes.map((anime) => ( <AnimeList title={anime.title} /> ))} </Div> ); };所感
大元のスキーマや Query、Mutation さえサーバサイド側で決めとけば
あとはよしなにクライアントサイド側で好きなスキーマで Query や Mutation かけるのは便利ぃ
- 投稿日:2020-07-07T17:31:35+09:00
React npm ERR! 解消メモ
はじめに
暑くなってきて季節はもう夏ですね。
そんな暑い中エラーが出ると汗がだらだら。自分の代謝を恨みます。
就職を目指す駆け出しエンジニアの記事ですが、見てくださると嬉しいです!npm ERR!
React学習途中、npm startを実行するとnpm ERR!が吐かれました。
解消までに試したこと
To fix the dependency tree, try following the steps below in the exact orderに従ってみる
解決のための手順を示してくれているので、とりあえず1から4まで実行してみました。
1.package-lock.jsonをprojectフォルダーから消去
2.同じくnode-modulesも消去
3.package.jsonのdevDependenciesのjestを消去
4.パッケージマネージャーを基にnpm install↓
解決されませんでした。
jest??
ここで、少しじっくりみるとこの部分が気になりました
jestがエラーを起こしていそうですね。
( jestはテストに利用していました。)
どうやらcreate-react-appを実行した際に、既にnode-modulesのなかにjestがインストールされており、手動でinstallしたjestとバージョン違いが発生していたのかもしれません。
package.jsonからjestとbabel-jestを消去して、node-modulesも消去後もう一度npm installしてみます。↓
まとめ
早く解決できて良かった!!
- 投稿日:2020-07-07T02:07:19+09:00
SPA(シングルページアプリケーション)って何者
はじめに
以前React.jsで開発していた際に、SPAについて調べる機会がありましたので、記載していきます。
SPAとは
「単一ページでアプリケーションを構成すること」
なんだかよくわかりませんね。。。。まずは従来のアプリケーションとSPAを比較してみましょう。
◇従来のアプリケーション
1.ユーザ操作
2.サーバーにリクエスト
3.サーバーでWEBページを生成
4.クライアント側へWEBページを送信
5.サーバーから受け取ったWEBページを描画特徴
ユーザがリクエストする度にWEBページ全てが読み込まれることです。◇SPA
1.初期ページ読み込み(初期描画)
2.ユーザ操作
3.サーバーにリクエスト
4.サーバーからクライアント側へ差分データを送信
5.差分のみを更新特徴
最初のリクエストのみWEBページ全体を読み込む
その後は差分データ(JSONなど)を受け取りJavaScriptで必要な場所だけを更新する
※従来のものと違い、毎回ページ全体の更新をする必要がなくなる要するにSPAでは、ページ全体をロードするのは初回のみで
それ以降は、JavaScriptで差分のみを更新するということ。これが「単一ページでアプリケーションを構成すること」とどうつながるのかというと、
一つのHTMLに対してJavaScriptを用いて更新しているというのがポイントです。※おまけ
SPAを作成できるフレームワークとして「React」「Vue」などがあります。
これらは「仮想DOM」を用いて差分更新を実現しています。よければ調べてみてください。SPAのメリット/デメリット
◇メリット
・画面全体のロードが最初の描画のみなので、通信負荷や通信容量が削減されて画面表示の高速化につながる
・画面を表示したまま、コンテンツの変更が可能になる
(更新対象のみを変更するので「待ち」ストレスが無くなる)
・サーバー側でWEBページを生成する必要がなくなり、クライアント側とサーバー側が疎結合になる◇デメリット
・初期ページを読み込むのに時間がかかる
JavaScriptの記述量が増えるため、初期描画に時間がかかる
・開発の複雑化
表示側の多くをJavaScriptで制御する必要があるため以前感じていた疑問
SPAとして作ったアプリケーションでもボタン押下等のアクション後にURLが変更され、
画面遷移しているのではと思ったことはないでしょうか。あれは動的にURLをJavaScriptで変更し、画面の一部を更新しているだけで
擬似的な画面遷移を実現しているのです。
(ユーザ目線では画面遷移しているように見える。)例として簡単にあげます
Vue.jsでは「vue-router」を使用して、動的にURLを変更しています。
(一部抜粋)app.vue<template> <div> <p>テスト</p> <router-view/> </div> </template>「router-view」と記載されている箇所のみがURLによって
動的に「component」(画面のパーツのようなもの)を切り替えています。なので実際に画面遷移をしているのではなく、画面の一部がURLによって更新されているということです。
(ちょっと長くなってしまいそうなのでこの辺にさせていただきます。)まとめ
SPAはユーザへのストレスを減らし、UXをより良いものにしてくれると思います。
そのためにもちゃんと理解をして実装をする必要があります。ここまでずっとSPAを推しましたが、なんとなくSPAを選んだではダメです。
一つの手段にすぎないため、自分の知識を深め最適かどうかを判断することも重要です。
(自分にも言い聞かせてます。。。。。。。。)参考文献
参考にさせていただきました。
【qiita】
https://qiita.com/takanorip/items/82f0c70ebc81e9246c7a
- 投稿日:2020-07-07T02:07:19+09:00
SPA(シングルページアプリケーション)っていったいなんだ
はじめに
以前React.jsで開発していた際に、SPAについて調べる機会がありましたので、記載していきます。
SPAとは
「単一ページでアプリケーションを構成すること」
なんだかよくわかりませんね。。。。まずは従来のアプリケーションとSPAを比較してみましょう。
◇従来のアプリケーション
1.ユーザ操作
2.サーバーにリクエスト
3.サーバーでWEBページを生成
4.クライアント側へWEBページを送信
5.サーバーから受け取ったWEBページを描画特徴
ユーザがリクエストする度にWEBページ全てが読み込まれることです。◇SPA
1.初期ページ読み込み(初期描画)
2.ユーザ操作
3.サーバーにリクエスト
4.サーバーからクライアント側へ差分データを送信
5.差分のみを更新特徴
最初のリクエストのみWEBページ全体を読み込む
その後は差分データ(JSONなど)を受け取りJavaScriptで必要な場所だけを更新する
※従来のものと違い、毎回ページ全体の更新をする必要がなくなる要するにSPAでは、ページ全体をロードするのは初回のみで
それ以降は、JavaScriptで差分のみを更新するということ。これが「単一ページでアプリケーションを構成すること」とどうつながるのかというと、
一つのHTMLに対してJavaScriptを用いて更新しているというのがポイントです。※おまけ
SPAを作成できるフレームワークとして「React」「Vue」などがあります。
これらは「仮想DOM」を用いて差分更新を実現しています。よければ調べてみてください。SPAのメリット/デメリット
◇メリット
・画面全体のロードが最初の描画のみなので、通信負荷や通信容量が削減されて画面表示の高速化につながる
・画面を表示したまま、コンテンツの変更が可能になる
(更新対象のみを変更するので「待ち」ストレスが無くなる)
・サーバー側でWEBページを生成する必要がなくなり、クライアント側とサーバー側が疎結合になる◇デメリット
・初期ページを読み込むのに時間がかかる
JavaScriptの記述量が増えるため、初期描画に時間がかかる
・開発の複雑化
表示側の多くをJavaScriptで制御する必要があるため以前感じていた疑問
SPAとして作ったアプリケーションでもボタン押下等のアクション後にURLが変更され、
画面遷移しているのではと思ったことはないでしょうか。あれは動的にURLをJavaScriptで変更し、画面の一部を更新しているだけで
擬似的な画面遷移を実現しているのです。
(ユーザ目線では画面遷移しているように見える。)例として簡単にあげます
Vue.jsでは「vue-router」を使用して、動的にURLを変更しています。
(一部抜粋)app.vue<template> <div> <p>テスト</p> <router-view/> </div> </template>「router-view」と記載されている箇所のみがURLによって
動的に「component」(画面のパーツのようなもの)を切り替えています。なので実際に画面遷移をしているのではなく、画面の一部がURLによって更新されているということです。
(ちょっと長くなってしまいそうなのでこの辺にさせていただきます。)まとめ
SPAはユーザへのストレスを減らし、UXをより良いものにしてくれると思います。
そのためにもちゃんと理解をして実装をする必要があります。ここまでずっとSPAを推しましたが、なんとなくSPAを選んだではダメです。
一つの手段にすぎないため、自分の知識を深め最適かどうかを判断することも重要です。
(自分にも言い聞かせてます。。。。。。。。)参考文献
参考にさせていただきました。
【qiita】
https://qiita.com/takanorip/items/82f0c70ebc81e9246c7a