Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

作りたいWebアプリのアイディアを迷走せずに作る方法。まず、エディターを閉じることから始めよう

何かを作りたいときは、エディターをいきなり起動してはいけません。 エディターを閉じて、まずはイメージをまとめることに集中しましょう。

なぜこの文章が必要か

なぜ何かを作る前にイメージをまとめる必要があるのでしょうか? 頭の中には完璧な作りたいもののイメージがあることでしょう。 であれば今すぐにでもプログラミングを始めるのが賢明なように思えます。

ですがそうしてはいけません。理由は「作りたいもののイメージは単なる幻想だから です」。

頭のなかにあるイメージはとても素晴らしいものですが、多くの場合は曖昧で、触れられない、価値を検証できないものです。 それを一旦書き出して、まとめていく方法を知っておきましょう。 まとめていく中で作るものがより明確になり、自分でも気づかない価値を発見できます。

  • 作るものをまとめて検証することで、作り始めた後の手戻りを防ぎます
  • 作るものをまとめて明確にすることで、作り始めた後に迷子になるのを防ぎます
  • 作るものをまとめて作業を見積もることで、最小のコストで最大の成果を得られるものから作り始められます

実際には作ってみるまでは価値は分かりません。ですが、何かを作るのはとても高コストです。 本当に天才的な人であれば全てを頭の中でまとめられるかもしれませんが、人は持っている手札で戦うしかありません。

イメージをまとめて検証することで、コストを小さく、精度を比較的高く価値を検証したうえでプログラミングができるようになります。

前提として作るもの

作るもののまとめかた、モックアップの書き方や設計の仕方を、何の実例もなく説明するのは不可能です。 この文章ではWebアプリケーションとしてのECサイトを作りながらノウハウを伝えます。

ECサイト(ショッピングサイト)には以下のような機能が考えられます。 今回のECサイトでは、お昼ご飯用のお弁当を購入して届けてもらうようなWebアプリケーションを考えます。

  • 商品を見る
  • カートに入れる
  • 商品を買う

お弁当を実際に販売するのはサービス事業者でなく、「〜〜弁当」のような実店舗を想定します。 サービス運営者は各店舗にお弁当を登録してもらい、ユーザーが購入するとサービス事業者の配送スタッフが運送します。

この文章ではブラウザーから利用するWebアプリケーションを元に説明しますが、他のスマートフォンサービスやバックエンドのAPIサーバなどにも役に立つ知識になります。 他にも、設計やソフトウェアを作る考え方やプロセスを学んでおけば、スクレイピング処理やバッチ処理を作る場合にも活用できます。 もちろん自分で作るだけでなく、他の人に頼まれて何かを作る場合にも活用できるよう書かれています。

ものを作るには流れが大切

何か新しいものを作るのはとても高度な技術です。 以下のような悩みはだれしもあるかとは思います。

  • 何かを作りたいけど何から始めれば良いか分からない
  • 人にタスクを依頼されて機能の追加はできても、自分で1から作るのは難しい
  • 作り始めてもすぐに目的がブレて迷子になってしまう

大切なのは ものを作る流れを知ること です。

  • イメージや用語、価値を書き出す
  • システム構成やモデルなど大局的な設計をする
  • アプリケーション、プログラムを設計する
  • プログラムを作る、育てていく
  • プログラムをテスト、レビューする

すぐにプログラムを書こうとするのはやめましょう。 今は エディターを閉じましょう。ターミナルを閉じましょう。技術調査をやめましょう。 気持ちや技術先行で作り始めても、迷子になったり大きな手戻りが発生するので無駄になってしまいます。 遠回りしているように感じますが、大きな手戻りが発生したり価値そのものを見失うリスクに比べれば小さいと考えましょう。

たとえば、以下のような手戻りや無駄な実装は往々にして発生します。

  • ソーシャルログインでTwitter, GitHub, Google, Amazonに対応させようとした
    • 実装に1ヶ月かかったけど、サービスのメインになる機能はまだ1つもできていない
    • 使う人は限られているので、ソーシャルログインは不要だった
  • スマホアプリとWebサービス両対応で作ろうとした
    • 最初に扱う商品の購買層は日中の会社員などなので、最初はWebだけで十分だった
  • 商品のレコメンドやオススメを、協調フィルタリングディープラーニングでやろうとした
    • 最初のリリースをしたときには商品の数や種類が少ないので、サイト運営者が選んだ「月間のオススメ商品」を表示すれば十分だった
  • 同じ商品でも色、サイズ違いが選べる機能と作ろうとした
    • 最初に扱う商品には色、サイズ違いがある商品はほとんどなかった
    • 色、サイズ違いがあっても数種類なので別の商品として扱えば十分だった

プロセスよりも大切なもの

この文章では設計という流れ(プロセス)を説明して、もの作りの実践に役立つ方法を説明しています。 ですが、プロセスだけでは不十分です。プロセスは手助けやサポートをするものであり本質ではありません。 もの作りを繰り返すことで磨かれるスキルや、作る中で考えていくことが一番大切なことです。 この文章では何かを作る手助けになるプロセスを説明しますが、実際にやって学んだ経験(スキル、中身、コンテンツ)こそが大切だと覚えておいてください。

何を実現したいかを明確にしよう

手戻りや無駄な実装を回避するために、まず実現したいものを 文章に書き出して明確にしましょう 。 作りたいものは何かを考えましょう。使い手の痛み、悩みに共感して、それを 解決する価値を検証しましょう

この文章では 価値 というものは「実現されることで実現されることでうれしくなる、豊かになること」、 「実現されることで楽になる、痛みが解消されること」と考えています。

実現したいものを書き出す方法

文章に書き出すにも、その観点がないと書き出すのは難しいことと思います。 価値問診票 というものを考えてみましたので、下の質問に答えながら作りたいものが解決する課題、価値を掘り下げていきましょう。

質問1. どんな痛みを解決するもの?

これから作りたいものは、どんな問題や痛みを解消するものですか? 本質的な解決すべき課題や満たすべき要望を明確にしない限り、その解決策(Webアプリケーションなど)を作っても無駄になってしまうのでとても大切です。

例:

  • 仕事に集中していたいのにお昼ごはんを食べる必要がある
  • ランチのためにでかけるのがめんどう
  • 食べるものを決めるのもめんどう
  • 毎日同じ場所で食べるには飽きてしまった

要望や痛みの本質には、人間の本質的な欲求や怠惰、不安があります。 解決する要望、痛みの中に、以下のような人間の本質を見出しましょう。

  • めんどうである
    • 買いに行くのがめんどう
    • 人と話すのが億劫だ
  • 不安
    • 自分がいつ事故にあって働けなるか分からない不安
    • 自分のスキルが5年後にも通用するか分からない不安
  • (時間、お金を)無駄にしたくない
    • チームメンバに効率的に仕事をして欲しい気持ち
    • せっかくお金をかけて海外旅行に行くのに台なしにしたくない気持ち
  • 強くなりたい、自分を磨きたい
    • より効率的に仕事をしたい
    • いつまでも若々しくありたい
  • 共有したい、自分を知ってほしい
    • 自分が食べているものが美味しいと知ってほしい
    • 自分の悩みや言葉を単に聞いてくれる人が欲しい

この文章を読んでいる方には、自分が成長して自分でアプリケーションを作れるようになりたい気持ちや、 手戻りに発生する無駄な時間をなくしたいという気持ち、チームメンバを育てて仕事をこなしてほしい気持ちがあるかもしれません。

質問2. 痛みの大きさや頻度は?

「要望」、「痛み」と言ったときに、その 程度 はどれほどのものでしょうか。 たしかに要望があるかもしれませんが、それがあまりにも些細な場合は解決する意味はありません。

  • 要望や痛みの 大きさ は?
    • 麻酔が必要:とても欲しい / 死ぬほどの痛みがある
    • 頭痛薬が欲しい:強く欲しい / つらいくらいの痛み
    • ビタミン剤を取ろうかな:あればうれしい / 気になる程度
  • 要望や痛みの 頻度 はどのくらい?
    • 毎日
    • 毎週
    • 毎月

「ランチを選ぶのがめんどう」という痛み1つであれば頻度は毎日ですが、大きさは「あればうれしい」程度です。 ただ「外に行くのもめんどう」や「オフィス近くの食事は飽きてしまった」のような痛みを併せることで解決する価値がでてきます。

たとえば「確定申告をしないといけない、できないしめんどうだ」という悩みは「かなりつらい痛み」という大きさですが、頻度は毎年1回しかありません。 ですが、「日々の経理処理がめんどう」、「レシートを管理しきれない」のような悩みがあるのではないか?と考えれば、軽微であれ日々の痛みとしてもどうじに解決できそうです。

痛みの大きさと頻度を考えることで、どれだけ作りたいものに価値があるのかを考え直せます。 また「満たせていない空白」に注目することで新たな価値に気づけます。

質問3. だれの要望、痛み?

要望や痛みの本質、程度を見極める中で だれの悩みなのか の像が徐々に浮かび上がってくるでしょう。 その「お客様」を次に明確にして書いておきましょう。 いちばん大切なのは、 使う人の要望、痛みに共感すること です。ありありとその人が使う姿、ストーリーが想像できるのが大切です。

理想的には 具体的に一番喜びそうな一人 が思いつけば一番です。さらに言うと自分や自分たちの組織であれば最良です。 なぜなら、作る人自身が使う人の要望、悩み、痛み、ストーリーに強く強く共感できるからです。

  • 「同僚の中村さんはいつもお昼ご飯の食べる場所を決め兼ねている。仕事も忙しそうだし集中できるようにしてあげたい(=> 何か良い解決策を用意してあげられないか?)」
  • 「取引先のチームリーダーの鈴木さんは、いつもとてもお忙しそうだ。こんな悩みありそうで大変そうだ(=> こんなものを作れば助けられるのではないか?)」

もし具体的な一人が分からない場合にも、どんな人がどういう場合に困るのかを調べたり、聞いたりすると良いでしょう。 たとえばSNSで調べてみたり、知り合いに悩みを聞いてみると良いかもしれません。

  • 仕事に忙しいエンジニアの人、年齢は20〜40歳
  • チームリーダーの人。チームのスキルアップをしたいが、教育の文化や自学自習する習慣も組織で教えていきたい

だいたいの年齢やWeb、スマートフォンにどれくらい慣れ親しんでいる人かもわかると、今後の機能やユーザーインターフェースを決める際の助けになります

  • Web画面を使ったときに理解できるか
  • 普段はPCを使うのか、スマートフォンを使うのか
  • 支払いの方法は何が良いか
    • 個人のクレジットカードを持っているか
    • 請求書のやり取りのほうが良いのか

なぜ書き出すのか

なぜ作る意味があるのかを書き出しておく理由は2つあります

  • 思考を書き出すことで曖昧な理解が明確になる
  • 中心的な価値に集中して作れるようになる
    • 無駄な作業、コストをなくす
    • 手戻りを防ぐ
  • 最小で最大の価値がある「初期リリース」を見極めやすくなる

この文章では価値問診票という書き方を提案しましたが、作りたいもの、実現したい価値を書き出す方法であれば他にどんなものでも構いません。 以外にも、以下の方法を使って製品、ビジネスや戦略の価値を検証できます。

匠Method: 〜新たな価値観でプロジェクトをデザインするために〜

匠Method: 〜新たな価値観でプロジェクトをデザインするために〜

書き出しておかないと「自分の都合の良いようにビジョンを進むべき道を変えてしまう」おそれがあります。 たとえば「この新しい技術を使ってみたい」という気持ちが、「ユーザーさんはこういう機能が欲しいのではないか」と都合の良いように解釈を捻じ曲げてしまうことはよくあります。 使う人の課題や痛みに定期的に立ち返るようにしましょう。使う人が求めていない機能や仕様を、作り手の都合で作ってはいけません。

「今使っているちゃぶ台だと仕事中に腰が痛くなってしまう」という課題を解決しようとしていたのに、「昇降機能付きスタンディングデスク」や「天然杉製のデスク」が欲しくなったりすることはだれしもあると思います。 デスクチェアーの「リクライニング機能があるかないか」、「ロッキング機能があるかないか」、「色は何色が良いか」といった本質的でない検討事項に人はすぐ陥ってしまいます。 そうならないように、自分の抱えている課題、求めている机の寸法、置く場所の広さ(制約条件)や値段(コスト)を忘れないように書き出そう、というのがこの価値問診票の意味です。

お弁当ECサイトの価値は何だ

この観点で、この文章で「作りたい」ランチ用のECサイトの価値問診票をまとめてました。

  • どんな痛みを解決するもの?
    • 仕事に集中していたいのにお昼ごはんを食べる必要がある(仕事をより効果的なものにしたい)
    • ランチのためにでかけるのがめんどう(外に出る、人に会う、オーダーをして会計をするのがめんどう)
    • 食べるものを決めるのもめんどう
    • 毎日同じ場所で食べるには飽きてしまった
  • 痛みの大きさや頻度は?
    • 大きさ:あればうれしい(4つ)
    • 頻度:毎日(4つ)
  • だれの要望、悩み?
    • 同僚のエンジニアの中村さん
    • 著者自身の悩み
    • 仕事に熱心に取り組む人
    • 出かけたり店員の人と話すのが少し億劫に感じる人
    • ランチには800円から1200円ほど使う人
    • 年齢は20〜40歳ほど
    • 仕事ではPCを使っていて、PCを使って注文する
    • 個人のクレジットカードは十分に持っている

問診票に答える中で、ストーリーや必要そうな機能、要件がボンヤリと見えて来ました。 痛みとしては小さいですが、日々の何気ない手間を排除することが製品の価値になりそうです。 単にお弁当を売るECサイトでなく、「仕事に集中していたい」や「出歩いたり店員の人と話すのが億劫」という気持ちがあることに気づけました。

次に、どういったものを作るかを問診票の下に追記しましょう。 あとで画面モックアップを作る際に役立ちます。

  • Webアプリケーションで作ると良いだろう
    • サイト上でランチを注文すると30分程度で届けるもの
  • 人と話さなくて済むようにしたい
    • お金はWeb上から支払える

また、実現するためにビジネス、業務上必要なことも決めておきましょう。

  • たとえば近所のお弁当を売っている飲食店のお弁当を売る
    • サービス提供者がお弁当を作る必要はなくなる
    • お弁当の更新などは飲食店に入力してもらう
  • 配達は自分たちで行なう

やらなくて良いことを明確にしておくことで、将来的に作る必要のある画面や処理の数を大幅に減らせます。

作りたいものに似たサービス、システムを調査しよう

作るべきものが見えてきました。ここで他に似たサービスやシステムを調査しましょう。 競合の分析を細かくしたり、張り合う必要はありません。 他サービスの提供価値とメインの顧客層から自分のアプリケーション、サービスの立ち位置を見直すために調査します。 また、ユーザーインターフェースやビジネスの仕組み、支払い方法の工夫などを学べます。

以下の方法で調査するのが良いでしょう

  • Googleで似たサービスがあるか検索する
  • GitHubオープンソースのアプリケーションとしてあるか調べる
  • 社内で聞いて過去に似た事例がないか調べる

一見似たものがあっても、提供する価値やターゲットになる人が違えば新しい価値になるので過敏にならないようにしましょう。 日中の忙しいエンジニア(オフィスでランチに1人〜数人)をターゲットに考えているのであれば、宅配ピザ(夕食に自宅で複数人)は競合と考える必要はありません。

競合や似たシステムの分析から始めてしまうと自分たちの作りたいものがブレてしまいます。 まずは価値問診票を通して、実現したいものが何かを先に書き出しておきましょう。

今回のお弁当ECサイトではAmazon出前館やUberEats、近所のコンビニなどが似たサービスとなります。 ですが、安易に「Amazonのあの機能を作ろう」と考えてはいけません。あくまで参考に学ぶために調査しておきましょう。 (Amazonにはあの機能があるのだから作ろう、作らなくてはダメだと考えないこと)。

何を実現したいかを明確にできましたか?

たとえ自分一人で作っている場合でも、書き出すことはとても大切です。 書き出す過程で『明確になっていない空白』に注目することが大切です 。

まずは1時間、時間を取って書いてみましょう! 将来的に何度も振り返って、書き直して良いです。安心してまずは実際に書き出しましょう。 繰り返すうちに上手になっていくので、模擬的にでも実際にやってみるのが良いでしょう。

本質的な要望、痛みを見出しすことで、これから作るもの、そして 作る必要のないもの を見極める材料を準備しました。 これから作るものそのもの、作る機能、用語の選択に至るまで、常にここで明確にした課題を意識して、判断の根拠にしましょう。

絵に描き出すことがすべての始まり

文章には限界があります。 「百聞は一見にしかず」や「一枚の写真は1000語にも匹敵する(a picture paints a thousand words)」のような ことわざにもあるように、絵に描き出すことで作りたいもののイメージや、システムの流れを俯瞰できます。 必要な仕様や機能、データなどを洗い出す(考え出す)ためにも絵に描き出すのはとても効果的です。

画面モックアップを書いてイメージを膨らませよう

Webアプリケーションの場合、実際に使ったときの使い心地がアプリケーション自体の質としてとても重要になります。 単に色味やフォントの質という意味でなく、入力のしやすさや表示される情報の量や質、遷移のわかり易さが使い心地を左右します。

そのためには実際に作って触ってみるしか検証する方法はありません。 ですがWebアプリケーションを開発するのはコストが大きいです。開発せずに確認するために 画面モックアップ を作りましょう。

画面モックアップは、各画面の表示されている要素や遷移、配置をかんたんに描き出した絵のことです。

  • 入力する情報、遷移、表示される情報から使い心地を確認する
  • 画面の仕様書としてまとめて、Webアプリケーションの仕様、用語、必要な機能やデータを洗い出す

単純に「使い心地」を検証するためだけでない点が重要です。 モックアップを通して仕様や機能を明確にすることが大切と考えましょう。

この文章では画面モックアップ(やモックアップ)と呼びますが、「スケッチ」や「ワイヤーフレーム」とも呼ばれます (描く絵の細かさによって呼び方を変える場合がありますが、ここでは扱いません)。

色や、細かい文言は描かなくて良いので、以下のような絵を描きます。 絵は白黒を基本として、各画面に必要な要素、おおまかな配置や遷移に注目して描きます。

f:id:hirokiky:20181102155827p:plain

f:id:hirokiky:20181102155839p:plain

絵を描くには紙にペンで書いても良いですし、BalsamiqMockupのようなツールを使っても良いです。 上記の例ではBalsamiqMokupを使っています。

ビジュアルに こだわれない ツールを使うほうが良いでしょう。 色味や細かいボタンのデザインにこだわるのは現時点では不要です (ボタンや画面そのものがなくなる可能性が十分にあるからです)。

モックアップに描き出すときのポイント

モックアップに描こうと言われても何をどれくらいの深さで描けば良いかは分からないでしょう。 ここでは、「仕様としての意味を含めた」モックアップを描く際のポイントをお伝えします。

このポイントは、モックアップに今まさに描き出す、描いている間に気をつけるポイントです。

落書きでなくちゃんと完成させよう

落書きやメモ程度の完成度にしてはいけません。 アイディアを描き出してみるためには良いですが、その状態で「画面仕様」としてはいけません。 将来的に画面仕様が変わることは大いにありますが、現時点で考えられる仕様を描きだして、曖昧さがないようにしておきましょう。

きちんと描き出さない問題点は、 「まだ完成していないだろう」と頭で考えてしまうこと にあります。 絵が未完成だと「まだ曖昧な部分があるな」と分かっていながら、その仕様を曖昧なままにしてしまいます。 曖昧なまま進めてしまうと、後になって大規模な集計が必要になったり別のテーブルやミドルウェアが必要になる恐れがあります。

たとえば以下のような絵では必要な要素が十分に見えてきません。

f:id:hirokiky:20181102155725p:plain

頭の中には他にも描き出すべき仕様や、考慮の足りていない部分があるはずです。

  • この画面にはどこから遷移するのでしょうか?
  • どこに遷移できるのでしょうか?
    • 見たところリンクは見当たりません
    • 「タイトル1」をリンクにするのであれば、リンクとわかるように色を変えるか、下線を引くと良いでしょう (専用のツールであれば「リンク」の設定も可能です
  • ブラウザーやアプリ全体の枠は描くようにしましょう
    • この絵が画面全体なのか、一部分なのかが分かりません
    • ナビゲーションバーやサイドバーが付く想定であれば、形だけでも描いておくと良いでしょう
  • 表示されている3つの要素は、どういった条件でフィルタリングされた要素なのでしょうか?
    • 「今月のオススメ弁当」など見出しを書くと、仕様が明確になりますしユーザーの方にも親切です

一番コアになる画面に注力しよう

画面を描くときはそのWebサービスたらしめる画面から描きましょう。

概ね作りたいWebサービス(やアプリ)の中で思いつく画面の順に描きだせば良いでしょう。 それは、想定する使い手のストーリーに関わる画面だからです。

トップ画面を見る => 商品一覧を見る => 商品を選ぶ => カートに入れる => 支払いをする

  • トップページ
  • 一覧ページ
  • 商品のページ
  • カート
  • 支払い

ECサイトであればユーザーのプロフィール設定やパスワード設定画面は優先度が低い画面です。 モックアップとして描く順番は後でも良いですし、画面が必要になるまで書かなくても問題にはなりにくいでしょう。 価値検証としての重要度も低いですし、後に必要な重要な仕様が潜んでる可能性も低いからです (開発の初期段階に自分で動作を確認するときにも、ユーザー登録画面やユーザーのパスワード設定画面はなくても良いでしょう。 手動でデータベースを操作したり、Webフレームワークの持つ管理画面からデータを作成すれば十分だからです)。

「描かれていない空白」に注目して情報を追加する

モックアップに情報を描き足していくときには、描かれている部分ではなく 描かれていない空白 に注目しましょう。 そこに足りない情報が、明確にすべき情報です。

たとえば「何かの一覧」があるのであれば以下のようなことが疑えます。

f:id:hirokiky:20181102155743p:plain

  • 画面上の空白

    • 他に求められる情報はあるか(表示する必要のない情報はあるか)
  • 仕様上の曖昧な言葉

    • 「一覧」とは何なのか
  • 定石で考えて足りない仕様

    • 一覧画面であれば検索、表示順、条件での絞り込み、ページネーションや「もっと見る」リンクが考えられます
    • 不要であればなくても良いですが、発想の糸口として考えてみましょう
    • 他のWebサービスやアプリを参考にして、一般的にどのようなUIがあるのかを定石として知っておくと良いでしょう

描かれている部分よりも、描かれていない部分に注目して仕様を明確にしていくことが重要です。 もし検討した末に「表示しなくて良い」と判断したのであれば、メモ書きとして経緯を書き残しておきましょう。 また同じ検討を避けるために残す意味があります。

すべては入力、遷移、表示の3つで決まる

「画面仕様」として重要なポイントは以下の3つだけです。

  • 入力
    • 「この画面ではどんな入力をするのだろう」
  • 遷移
    • 「この画面にはどこから来て、どこに行くのだろう」
  • 表示
    • 「この画面ではどんな情報が表示される(表示しなくて良い)のだろう」

この3つに注目して各画面を描くようにしましょう。 入力と表示、遷移に注目することで、以下の仕様が明確になります。

  • ユーザーのストーリー、価値にあう画面ができているか
  • どんなデータが仕様上必要か

以下のような観点を持って画面モックアップを描くと良いでしょう。

  • 入力
    • どの画面で必要な情報を入力するのか
      • 商品を「カートに入れる」ときに「数量」を指定するのでしょうか
      • 使いやすさを考えると数量は「カート画面」で入力できれば十分かもしれません。
      • ユーザーは商品のレビューをいつ、どの画面から入力するのでしょうか(別の画面が必要かもしれない)。
    • どんな方法で、どんな型のデータを入力するか
      • テキスト入力なのか、選択式にするのかなど入力の種類を決めます
      • データは数値なのか、文字列なのか、日付なのか決めます
    • ボタンにはどんな種類があるか考える
      • ボタンは「ユーザーがデータを変更する」ときのアクションになるので重要です
      • 「カートに入れる」ボタンだけでしょうか、「商品をお気に入りにする」という仕様も必要だったかもしれません
  • 遷移
    • どの画面から、どの画面にユーザーが移るのか
    • ユーザーが始めてそのWebサービスを使うとき、どこでその画面の存在を知るのか
      • 重要なページであればナビゲーションバーにリンクがあったほうが良いでしょう
      • 何度もクリックしないと行き着けないページはだれも使わなくなります
    • ボタンを押すとどこに移動するのか
      • リンクだけでなくボタンをクリックしたときも画面を遷移できます
      • 「カートに入れる」ボタンを押したときには「カート画面」に移動するのでしょうか?それともそのページのままでしょうか
  • 情報
    • 画面に必要な情報のみ表示する
      • 一覧画面では不用意に多くの情報は表示すべきではありません
      • 一覧画面で商品の説明文や、商品の大きさなどは表示しなくて良いでしょう
    • 「詳細画面」から必要なメタデータを明確にする
      • 詳細画面で表示する情報を考えることで、必要になるデータを洗い出せます
      • たとえば食品であればアレルギー情報は表示すべきでしょう
    • 表示されるデータはどこで入力されたものか
      • 「ユーザーの住所」や「レビュー」などの情報はどこで入力されたものでしょうか
      • もし別途画面が必要であれば、だれが、いつ(どんなストーリーで)、どの画面から入力するのかを考えて描きましょう
    • 「タイトル」や「本文」の他に、値段や販売個数、セール、タグやカテゴリーなどを表示するか
      • 「定石」から足りない要素を発想すると良いでしょう
    • どんな「日」の記録が必要か
      • 「公開日」、「編集日」、「作成日」など何かが起こった日付を表示する必要はあるでしょうか (編集されないデータであれば「編集日」をもつ必要はありません)

もちろん画面上の配置や、どの要素を強調表示するかどうかも大事ですが、 ユーザー体験やストーリーを元にしたWebアプリの価値を把握できるレベルであれば十分でしょう。

モックアップから仕様を読み解いてみよう

モックアップは表示する情報や使い心地を検討するだけでなく、仕様書としての意味合いがとても強いです。 ここで、描き出したモックアップから仕様を読み取る方法をお伝えします。

ただモックアップを描くだけでなく、そのモックアップから後に必要な仕様を読み取ることが大切です このような観点を持つことで画面モックアップは「単なる画面の下書き」でなく、未来に必要な仕様や設計の青写真と捉えられます。

  • どのようなデータ(テーブル、モデル)が必要か
  • 各画面を表示するために、どうデータを取得する必要があるか
  • キャッシュや集計する処理が必要か

ECサイトのトップページから、後々に必要になるモデル、ミドルウェアや集計処理を読み解きましょう。

f:id:hirokiky:20181102155800p:plain

まず、概念として、どのような「もの」があるかをおおまかに捉えてみましょう。

  • 商品
    • 画像の「のり弁当」など
    • 販売されているお弁当そのもの
  • 販売業者
    • 画像の「BeProud弁当」など
    • お弁当を実際に作って売っている店舗
  • ユーザー
    • サービスにログインして購入するユーザー

それぞれのモデルに、どのような属性があるのかもモックアップから読み取れます。 細かくER図などに書き出すのは後で良いので、ここではどんなモデルがあるのかのみ見ておきましょう。

次に、画面内にある要素や単語の意味を深く考えていきます。 現状では機能の一覧や、実装の細かな点まで考慮する必要はありませんが、 ある程度必要になる処理を想定しておくことで、複雑すぎる処理が潜んでないかなどを考えておきましょう。

  • 「お弁当の検索」:お弁当の検索とは、お弁当のどの情報をから検索するのか?
    • 現段階では「お弁当の名前」と「お店の名前」からのみ検索する
    • 検索はデータベースのLIKE検索で十分だろう
  • 「お届先住所」
    • ユーザーはいつお届け先住所を入力するのだろう?
    • 複数登録できて、よく使う住所を1つ設定しておけると良いだろうか?
  • 「配達時間の目安」
    • 何を元に配送時間は算出されているのか?
    • 店舗の住所とユーザーの「お届け先住所」から算出しているのだろうか?
    • 算出はプログラム上ですべきか、地理情報の扱えるデータベースですべきか
    • 地理的な距離だけでなくメニューの準備にかかる時間も加算すべきか
  • 「配達の早い順」
    • 店舗の住所とお届け先の住所からプログラムで計算するのであれば、データベースでのソートは不可能
    • 地理情報の扱えるデータベースを使って、2点間の距離を算出、距離からおおまかな時間を算出できればソートはできるだろう
  • 「評価」
    • 「評価」は1〜5点で付けられるものだろう
    • 表示されている「評価」は、商品ごとの今までのレビューの平均を算出したものだろう
    • 商品を表示するときに、商品ごとのレビューの平均をデータベースで毎度計算するのは遅いかもしれない
  • 「評価の高い順」
    • 商品のレビューの平均を計算して並べ替えするのは時間がかかりそう
    • 商品ごとの「平均評価」を5分ごとや10分ごとに算出して別途管理するのもありかもしれない
    • 「評価の高い順」を表示するとして、ユーザーの「お届け先住所」からあまりにも配達に時間が商品を表示して意味があるのか
  • 「画像」
    • 画像のサイズは4対3で固定するのか、自由なサイズを受け付けるのか? (切り取るのであれば、画像を扱うPythonJavaScriptのライブラリーを知っておく必要がある)
    • 画像はどこに保存するべきか。CDNを通して配信するべきか (未ログインユーザーもアクセスする負荷の大きい画面であればCDNは必要だろう)

この時点で要件を満たすために必要なモデルやミドルウェア、集計があまりに複雑すぎると気づくことがあるでしょう。 そういった仕様が潜んでいないかを気を付けて(実装をある程度想像しながら)モックアップを精読することにもモックアップに描き出す意味があります。

使う人の要望、痛みの大きさや頻度(それを解消するための仕様の重要度)を考えて、そのまま作るか、代替案を考えるか、仕様をなくすかを考えましょう。 「とても頑張った割にはだれも嬉しくない」ものよりも、本質的な価値にもっとも近い仕事に注力するためによく読むことが大切です。

アクセスする人の量と処理の重さを見積もる

各画面にどんな人がこのページにアクセスするのかを明確にしておきましょう。 アクセスできる人の量によってどのくらい高速にレスポンスするのかが変わってきます。

  • 未ログインユーザーもアクセスできる
    • アクセスする人数は少なくない(サービスが成長すれば、秒間数百リクエストのアクセスは十分考えられる)
    • キャッシュやCDNなどが必要になる
  • ログインユーザーのみアクセスできる
    • 初期であれば10〜数100ユーザー、成長していけば数1000〜数万ユーザーは考えられる
    • 全ユーザー数のうち、アクティブユーザーが5%〜20%と考えると、トップ画面のおおまかな負荷などが考慮できます
  • 店舗管理者やシステム管理者などの一部のユーザーのみアクセスできる
    • 管理者向けの画面は、負荷は大きくなりにくいです
    • 管理者向けのレポートや集計データの表示などをする場合は、アクセス数は少なくても処理としては重い処理になるでしょう

また、アクセスの権限管理がどれくらい複雑かをおおまかに知っておけます。 あとでモデル(テーブル)の設計をする際に、ユーザーアカウントに関するテーブルを設計する際の参考になるでしょう。

最初にどこから作るかを決めよう

何かを作るうえで、コストと締切りは無視できません。 仕事でプログラムする際にはもちろんコストと締切りは存在しますが、仮に自分ひとりで趣味のWebサービスを作る場合にもコストと締切りは存在します。

  • コスト
    • 自分自身の時間
    • 労力、体力
    • 作り続けるモチベーション
  • 締切り
    • 飽きてやめてしまう
    • 似たサービスがローンチされてしまう

締切りというと嫌な印象がありますが、モチベーションを保つうえでとても大切です。 途方もなく大きなものを闇雲に作るより、マイルストーンを立てて順に小さく作っていくほうがモチベーションを保てます。

最小の完成形を見つける

今までモックアップを書き出す中で、製品に必要そうな機能を洗い出してきました。 ですが、それら すべての機能が最初のリリースに必要というわけではありません 。 リリースをして自分で作ってみたり反響を得たりしながら、設計や仕様自体を柔軟に変更しましょう。

最小の製品はどうやって見つければ良いのでしょうか? 価値問診票を見ながら 最初に要らない 機能を決めましょう。 ECサイトが解決する痛みには以下のようなものがありました。

  • 仕事に集中していたいのにお昼ごはんを食べる必要がある(仕事をより効果的なものにしたい)
  • ランチのためにでかけるのがめんどう(外に出る、人に会う、オーダーをして会計をするのがめんどう)
  • 食べるものを決めるのもめんどう
  • 毎日同じ場所で食べるには飽きてしまった

解決したい問題を見ると、まず「オンラインでお昼ご飯が買えること」ができればOKだとわかります。 どの機能を優先すべきかを考える際は、以下のような観点で考えます。

  • 一番中心になる課題から解決する
    • その製品・サービスたらしめる機能
    • 利用頻度の多い、ユーザーのだれしもが使う機能
  • リリース当初不要なものはなくす

    • 商品の数(データ量)も少ないので高度な検索や並べ替えは不要だろう
    • ユーザーアカウントは管理者が手動で作って知人に配布すれば十分だろう たとえば、以下の機能は必須としました。
  • 商品の一覧ページ

  • 商品の詳細ページ
  • 配送先住所の設定
  • 配送時間の見積もり機能
    • 初期リリースは住所間の直線距離からおおまかに算出する
  • カート機能
  • 商品の注文機能
    • 同じ店舗の商品しか購入できないようにする
  • 購入履歴ページ
  • 売店、商品の管理機能

以下の機能は初期リリースには不要と考えました

  • 今月のオススメ商品機能
  • よく買うお弁当機能
  • レビュー機能
  • レビューの評価値の集計機能
  • ユーザー作成機能
  • 商品の検索、並べ替え機能
  • 成分表記、アレルギー表記

ただし、一見不要そうに思えても使い勝手やビジョンに大きく影響する機能は作る必要があります。 今回であれば「めんどうさ」をなくすためのWebサービスなので、最小の製品でありつつ使う手間は最低限になるようにしたいです。

なので「クレジットカードでの支払いをなくして、まずは現金で配達員に支払えば良い」とは限りません。 現金を扱うようにすることで、配達員のお金の処理や、販売店への支払いの業務設計が必要になることも考えられます。 その手間が自動化できることを考えてもクレジットカード決済は必須の機能でしょう。

ストーリーが満たせるかレビューする

初期のリリースする機能のモックアップができれば以下を考え直しましょう

  • Webサービスとして価値が実現できるか
  • 使う人のストーリーを実現する画面の遷移、ボタンが揃っているか
  • 使う人が触った瞬間に「求めていた価値」を感じられるか
    • 私には難しい、私にはあわない、私のモノじゃないと思われないか
  • 使う人にとって使いやすいか、使いこなせるか
    • 年齢やWeb、スマートフォンへどれくらい慣れているか
    • ユーザー層によっては「ハンバーガーアイコン」をみて「メニュー」の意味とは伝わらない場合がある
  • どういった流れで使い手は、その使い方を会得するのか
    • 画面を見るだけで使い方を想像できるか
    • 既存の他のサービスやアプリから機能や意味を想像できるか
    • 今までと大きく違う場合は、注釈やチュートリアルがあったほうが良いかもしれない

今後作りたい機能などについては詳細にモックアップを作らなくても良いでしょう。 はじめにリリースをしたあとに、フィードバックを受けながら次にリリースするマイルストーンを決めていけば十分です。 モックアップは一直線に完成までを作る必要はありません。 実現したい価値やリリース時期、システムの制約などを考慮しながら、行き来させながら作っていきましょう。

設計とは何か、どれくらいするものなのか

ここまでの話は「画面設計をしよう」という話とも言えます。

設計とは何かを実現するために事前に決めるための計画、図、仕様のことです。 どのようなものを作るのか、何を作るのかを明確にするために書き出されます。

最終的には(ソフトウェアなので)プログラムのソースコードが分かりやすい成果物になります。 完成品としてのシステムやWebアプリケーションが実現したいものです。

ですがいきなり最終的な成果物を作ろうとすると迷子になってしまいます。 たとえば大阪から(行ったことのない)東京に行くために、何も計画せず、考えずに車を発進させるようなものです。 人間味のあるドラマは生まれるかもしれませんが。

その最終的な成果物、価値の実現のために、より抽象的で高い視点から計画していくことが設計です。 「どんなものを作るのか」、「どういう画面なのか」や「どういう構造で作るのか」を決めていきます。 使う人にとっての価値(良さ)を高めることや、保守性、可読性、安定性を高めること、手戻りを少なく完成させることなどを高めることが設計の目的です。

設計は最初から100%の正解を求めてはいけません。作りながら徐々に変えていって問題ありません。 ですが、今の設計(計画)が「何%くらい確かなものか」(確度)は意識しておきましょう。 次の段階(より具体的な作業)に進んで問題ない(将来的な手戻りが少ない)レベルの設計を常にするようにしましょう。

プロセスとしての設計と構造としての設計

「設計」という言葉を聞くとき、以下の2つの場合があります。

  1. プロセスとしての設計
    • 計画や大枠の構造把握のために図や仕様をまとめるプロセスや成果物
    • 具体的なプロセスに進むのが早すぎる場合に「設計が足りない」という言葉を使う場合はこちらの意味
  2. 構造としての設計
    • 抽象的な構造やデータ間の関連、プログラムやテストの構造や作り
    • 保守性や安定性が高いという意味で「良い設計」という言葉を使う場合はこちらの意味

表面的に「設計」というプロセスが目に見えなくても、作業者の中で設計のプロレスが行われているはずです。

まとめ

何かを作りたいと思いついたときは、すぐにエディターを起動するのはやめましょう。 まず自分が作りたいものを書き出して、その価値を検証しましょう。 大局的な視点から徐々に詳細に降りていくことで、将来的な手戻りや迷走を避けられます。

なにか作りたいものはありますか?まずはそのイメージを膨らませて、何が欲しいかを明確にしましょう。 その「手触り」の中に本質があります。

仕事で書いた匠メソッドをCacooに移行した

先日、匠メソッドをCacooで書くととても良いという話をしました。 匠メソッドについてや、Cacooで使うメリットは以下を読んでください。

blog.hirokiky.org

そこで PyQ チームでもCacooを使って匠メソッドをしてみることにしました (もともと、開発当初から2年間ほどAstahを使って匠メソッドを書き続けています)。

チーム全員で使えるので、全員で同期してWebでそのまま閲覧、編集できるメリットはやっぱり大きそうです。 今までAstahを使っていましたが、Cacooを使うとチームで同期してメンテしていける点や、ミーティング中に全員で書き込める点などのメリットがあります。

まだ移行したばかりなので、今後より長い間使っていく中でのメリットやデメリットも伝えられるかなと思います。

Cacoo移行した匠メソッド

以下4つのモデルをCacooに移行しました (モザイク処理をしています)。

ステークホルダーモデル

f:id:hirokiky:20181020132854j:plain

価値分析モデル

f:id:hirokiky:20181020133026j:plain

価値デザインモデル

f:id:hirokiky:20181020132948j:plain

要求分析ツリー

f:id:hirokiky:20181020132534j:plain

おわりに

匠メソッドはメリットがたくさんある手法ですが、図がカオス化しやすかったり、メンテされなくなる問題はあります。

PyQ チームでは継続的にPyQの開発を続けているので、匠メソッドも常に見直して更新しつづける必要があります。 定期的に各ステークホルダーの課題や要求を見直すことで、小さなチームでもより効果的な仕事ができるように取り組んでいます。 継続開発するときこそ匠メソッドの、「お客様やステークホルダーの課題や価値に立ち返る。自分たちのビジョンと突き合わせる」という利点がより重要になると僕は思っています。

それを忘れてしまうと、なぁなぁにくだらないものを作ったり、人に言われるがままに物を作って、時間や労力を浪費してしまいます。 Cacooなどの、Webで同期できてチームメンバー全員で編集できる環境で匠メソッドを書くことで、よりその良さを活かせるのではないでしょうか。 ぜひ、匠メソッドを使っている皆さんはCacooで試してみてください!

Cacooで匠メソッドをやると、Webで同期するし同時編集もできるし良い、という話

何かを開発するとき、いきなりエディターを立ち上げていませんか?

製品、サービスを作るときは要求、要件を分析してまとめてから作るのがオススメです。 そんなときに匠メソッドという要求開発の手法を、僕個人も BeProud の仕事でも使っています。

匠Method: 〜新たな価値観でプロジェクトをデザインするために〜

匠Method: 〜新たな価値観でプロジェクトをデザインするために〜

匠メソッドは製品やサービスを「なぜ作るべきなのか」、「何が求められているのか」という要求を、ニーズとシーズから探る手法です。 匠メソッドについて知りたい人はこの本を読んでみてください。 (僕は少し自分なりに変えて使っている部分もあるので、この記事内の図などが少し違うなというところがあっても気にしないでください)。

匠メソッドをするときのよくある悩み

匠メソッドはツールを限定しません。 なので、テキトウなドローツールや付箋紙などでもできます。 聞くところオススメされているのは Astah というツールを使うことで、 匠メソッドのプラグインなども提供されています

ですが、正直なところ、これらの方法でやる 問題はいくつかあります

  • 紙などでやると、 中長期的にメンテしにくい。デジタル化できない
  • Astahなどでは 同時編集できないファシリテーターが図の編集も常にやる必要があってしんどい (Astahにも同時参照しつつ編集などの機能もあるようですが、匠メソッドのように全員が全員同じモデルを密に編集することはできないと思います)
  • オンラインで同期できない
  • ツールによってLinuxなどで使えないなど 環境依存 or インストールが面倒 だったりする
  • いちいち スクショしないとWikiなどに貼れない

ここで僕は Cacoo をオススメします。 僕は最近作ってる個人プロジェクトで、Cacooで匠メソッドをやってみているんですがかなり良いです。 Cacooは匠メソッドにもかなり有用に使えます。

Cacooで匠メソッドをしよう

Cacooはブラウザーで動作するグラフのドローツールです。 以下の利点があります。

  • 環境に依存しない
  • オンラインで同期できる
  • 同時編集できる

これは最of高と言わざるを得ません。 匠メソッドは複数人で共有して書いたり、中長期に渡ってメンテしつつ閲覧、編集することに意味があります。 ですので、誰でも常に見て、編集できることはすごく大切です (ただCacooの同時編集は、個人的に2ブラウザーで試した程度なので、何人もの人がオンライン越しに編集して匠メソッドがうまくいくかは分かりません)。

主に僕は「ステークホルダモデル」、「価値分析モデル」、「価値デザインモデル」と「要求分析ツリー」の4つを使います。 Cacooで4つの図をテンプレート的に書いてみたので見てみてください (仕事の内容が入っているものは見せられないので、テンプレートとして使っている図をお見せします)。

ステークホルダモデル

f:id:hirokiky:20181014152420p:plain

価値分析モデル

f:id:hirokiky:20181014152431p:plain

価値デザインモデル

f:id:hirokiky:20181014152442p:plain

要求分析ツリー

f:id:hirokiky:20181014152455p:plain

Cacooで共有

Cacooの図としても以下のリンクで共有しています。 閲覧のみは誰でもできるようにしています。

https://cacoo.com/diagrams/abZdFWFFiP3PYqED/C2575

テンプレートとして共有するのはどうすれば良いのか分からないですが。

新Cacooはとても良い

この要求分析ツリーなどは新しいCacooのUIで書いています。 新しいCacooを使うと匠メソッドが書きやすくなる良い点がたくさんあります

  • Styleという色味のプリセットがあるので、(要求などに使う)四角形などの背景色、文字色などを一発で指定できて便利
  • 指定済みのStyleを別のオブジェクトに適応できるので、価値分析モデルの「目的」からステークホルダーの要求にスタイルをコピーするとき便利

また全体的にとても使いやすくなりましたし、軽快に動作してとても良いです。

まとめ

匠メソッドをやっているけど Web同期できない同時編集できないファイル形式を気にせずWebで編集、共有したい という悩みがある人は、 ぜひCacooでやってみるのが良いと思います。

僕もまだ手探りで試しているところなので、同時編集してみてうまく回ったかや、大規模なモデルでも動作したかなど教えてください。

匠メソッドはとても有効な手法ですが、書捨てで忘れてしまっては意味がありません。 プロジェクトのメンバーが原点に立ち返りながら、中長期的にみんなでメンテできるようにしていきましょう。

gunicornでPython製Webアプリケーションを動作させよう(DjangoとFlask)

前の記事ではWSGIアプリケーションをWSGIサーバー(gunicorn)で起動する方法を説明しました。 ここではgunicornを使って、Python製WebフレームワークでできたWebアプリケーションを起動しましょう。

blog.hirokiky.org

なぜgunicornなどのWSGIサーバーを使うのか

DjangoやFlaskなどのWebフレームワークを使っているとき、開発時にもサーバーを起動して動作確認をしていると思います。 例えばDjangoであれば python manage.py runserver というコマンドでサーバーを起動できます。 なぜこのサーバーを使わずにgunicornを使うのでしょうか?

理由は簡単に言うと、動作が速いからです。

gunicornuWSGIwaitress といったWSGIサーバーは速く、 安定して動作することを考慮して作られています (何をもって「速い」と言うのかは別の機会に詳しく解説できればと思います)。

なので、一般に公開して多くの人に使ってもらうサーバーなどでは、専用のWSGIサーバーを使うほうが良いです。 「本番環境ではgunicornなど別のWSGIサーバーを使う」と、プラクティスとして覚えておくと良いでしょう。

gunicornのインストール

gunicornのインストールは、その他のPythonパッケージのように pip でインストールできます (ここではpipの詳細や、Pythonの仮想環境を使う方法については説明しません)。

$ pip install gunicorn

gunicornでWSGIアプリケーションを起動する

gunicornをインストールすると gunicorn というコマンドが使えるようになります。 WSGIアプリケーションを起動するには、この gunicorn コマンドを使って起動します。 以下の例では wsgi.py ファイル内の application というWSGIアプリケーションを起動しています。

$ gunicorn wsgi:application

ファイル中のWSGIアプリケーションの名前が application の場合、以下のように名前を省略できます。

$ gunicorn wsgi

どんなPython製のWebフレームワークを使う際にも「WSGIアプリケーションがどこにあるのか」を知っていれば、 gunicornなどWSGIサーバーを使って簡単に起動できます。

Flask製Webアプリケーションを起動する

FlaskでWebアプリケーションを作った場合、 app = Flask(...)インスタンス化した app 自体がWSGIアプリケーションです。 例えば myapp.py というファイル内に app という名前でFlaskアプリケーションがある場合、以下のように gunicorn で起動できます。

$ gunicorn myapp:app

Standalone WSGI Containers — Flask 1.0.2 documentation

Django製Webアプリケーションをgunicornで起動する

Djangoで作ったWebアプリケーションをgunicornで起動するには、Djangoのプロジェクトディレクトリー内で以下のように実行します (ここで言うプロジェクトディレクトリーは manage.py ファイルがあるディレクトリーの意味です)。

$ gunicorn myproject.wsgi

myproject というのは django-admin startproject ... で決めたプロジェクト名です。 DjangoでWebアプリケーションを作ると、 myproject/wsgi.py というファイル内が自動で作成されます。 この wsgi.py ファイル内の application という値(呼び出し可能オブジェクト)がWSGIアプリケーションです。 この wsgi.py は、 settings.pyurls.py があるディレクトリー内にあります。

How to use Django with Gunicorn | Django documentation | Django

python manage.py runserver コマンドも、この wsgi.py の application を使って起動しています)

Djangoの設定ファイル(settings)を切り替える

起動する際にDjangoの設定ファイル(settings)を切り替えるには、環境変数 DJANGO_SETTINGS_MODULE を指定します。 以下の例では myproject/settings/production.py という設定ファイルを使っています。

$ gunicorn --env DJANGO_SETTINGS_MODULE=myproject.settings.production myproject.wsgi

Djangoの場合、このようにして環境ごと(ローカル環境、本番環境ごと)に設定ファイルを用意して切り替えられます。 この例ではgunicornの --env オプションで指定していますが、環境変数に直接設定しても問題ありません。

まとめ

前回の記事 ではWSGIとは何かと説明しました。 今回はFlask、DjangoなどのメジャーなPython製Webフレームワークをgunicornという本番環境でも使えるWSGIサーバーで起動しました。

次は、gunicornに指定できるオプションの中でよく使うものを説明します。

Spacemacsでvue-modeかつflycheckする

emacs(Spacemacs)+ vueファイルをずっと模索している。

というのもjs2-modeがmmm-modeに対応しないので、JSを書くときにjs-modeで不便だったりする。 web-modeを使っても似たようなものなので、なんとかしたいこの頃。

模索中の設定

.spacemacs に以下追加。

dotspacemacs-additional-packages '(
    vue-mode
    lsp-ui
    lsp-vue
    company-lsp
)

user-configに以下追加

(require 'vue-mode)
  (add-to-list 'vue-mode-hook #'smartparens-mode)

(require 'lsp-ui)
  (require 'lsp-vue)
  (add-hook 'vue-mode-hook #'lsp-vue-mmm-enable)
  (with-eval-after-load 'lsp-ui
    (require 'lsp-ui-flycheck))

(require 'company-lsp)
  (push 'company-lsp company-backends)

グローバルにインストール

$ sudo npm install -g vue-language-server

HTMLのli要素でアイコンフォントを使って、かつ改行時にインデントを揃えるCSS

アイコンフォントを使って li 要素の list-style をカッコよくします。 li要素の list-style でアイコンフォントを一覧の頭に表示するには、以下のように擬似要素を使ってできます。 この例では Material Icons アイコンフォントを使っています。

ul {
    list-style: none;

    li {
        &:before {
            font-family: 'Material Icons' sans-serif;
            content: 'check_circle';
    }
}

f:id:hirokiky:20181003100502p:plain

font-familycontent を指定して <i class="material-icons">check_circle</i> と同じように表示させられました。

でもこうすると、改行のときに文字がアイコンの左側に行ってしまいます。

ささいなことですが、こういうところを手抜きすると一気にダサくなるので調子したいです。 以下のように li 要素にスタイルを追加するとうまくインデントします。

ul {
    list-style: none;

    li {
        text-indent: -1em;
        padding-left: 1em;

        &:before {
            font-family: 'Material Icons' sans-serif;
            content: 'check_circle';
    }
}

f:id:hirokiky:20181003100512p:plain

キレイにまとまりました。 やったー。

WSGIアプリケーションとは?WebフレームワークからWSGIサーバーまで

まえがき

このブログ記事は、ある大きなドキュメントの一部のために書いています。 WSGIを説明している記事やドキュメント、本はたくさんあるので、このブログ記事で新しく説明されることはありません。

本文

PythonのWebアプリケーションは WSGI という仕様に則って開発されています。 WSGIに則って作られたWebアプリケーション(WSGIアプリケーション)は、WSGIの仕様に則ったサーバー(WSGIサーバー)上で動作させられます。

例えばPython製WebフレームワークのDjangoやFlaskはWSGIの仕様に則っています。 これらのWebフレームワークで作ったWebアプリケーションは、WSGIサーバーで動作させられます。 メジャーなPython製のWebフレームワークはWSGIアプリケーションとして作られているので、WSGIを意識する機会は少ないでしょう。

WSGIで動作するWebフレームワーク:

https://wsgi.readthedocs.io/en/latest/frameworks.html

WSGIサーバー:

https://wsgi.readthedocs.io/en/latest/servers.html

WSGIについて詳しくは wsgi.org を読むと良いでしょう。

http://wsgi.org/

極論、WSGIは気にしなくて良い

極論を言い切ってしまえば、WSGはWebフレームワークやサーバーの開発者のためのものです (もちろんピュアWSGIでWebアプリケーションを開発することもできます)。

単に「Webアプリケーションを作りたいな」という人は、そこまで深く知る必要はありません。 以下の1つだけを覚えておくと良いでしょう

  • WSGIサーバーを使えば、Python製のWebフレームワークで作ったアプリケーションを動かせる

ですが、簡単にでも役割や仕組みを知っておけばエラーに遭遇したとき理解が早くなるでしょう。 WSGIサーバーのドキュメントを読む際などにも混乱することが減りますので、簡単にここで説明します。

WSGIアプリケーションを作ってみよう

WSGIという仕様」というと難しいように感じられますが、とても簡単な仕様です。 例えば以下のPythonの関数はWSGIアプリケーションです。

def my_wsgi_app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    body = "Method was {env['REQUEST_METHOD']}".format(env=environ)
    return [body.encode('utf-8')]

「本当にこれがWebアプリケーション?」というような関数ですが、WSGIアプリケーションです。 この関数を動作させて、ブラウザーでアクセスすると以下のように画面に表示されます。

f:id:hirokiky:20180930182908p:plain

関数の意味は何でしょうか。 それぞれ関数の引数と戻り値は以下のような仕様になっています。

  • environ: HTTPリクエストの情報(ヘッダーの値など)
  • start_response: HTTPレスポンスのコード、返すヘッダーを指定して呼び出すための関数
  • 戻り値: HTTPのボディーになるバイト型のイテラブル

この仕様を満たす関数を作れば、それはWSGIアプリケーションです。 WSGIアプリケーションはWSGIサーバーで動作させられます。 試しにこの関数を gunicorn というWSGIサーバーで動かしましょう。

my_wsgi.py という名前のファイルを作って、ファイルに上記の関数を書いているとします。 gunicornpip でインストールすると、ターミナルからサーバーを起動できます (gunicornのインストール方法などは他で説明します)。

$ gunicorn my_wsgi:wsgi_app

この my_wsgi:wsgi_app という引数は、 my_wsgi.py ファイル内の wsgi_app というWSGIアプリケーションを起動しろという意味です。 ここでブラウザーから http://127.0.0.1:8000/ にアクセスすると、画面には Method was GET と先程のように表示されます。

フレームワークWSGI

DjangoやFlaskのようなWebフレームワークは、ユーザーの書いたView関数やURLのディスパッチャーを読み込んで、呼び出し可能オブジェクトを作ります。 呼び出し可能オブジェクトとは foo() のように呼び出せるオブジェクトで、先程の wsg_app 関数も呼び出し可能オブジェクトです。

この呼び出し可能オブジェクトが、WSGIアプリケーションです。WSGIサーバーはこのWSGIアプリケーションを読み込んで、ブラウザーなどにHTTPを通して結果を返します。

  • ブラウザー: HTTPでサーバーと通信する
  • WSGIサーバー: HTTPの解釈、WSGIアプリケーションを呼び出し、結果をHTTPで返すサーバー
  • WSGIアプリケーション: 上記仕様でHTTPの内容を返すPythonの呼び出し可能オブジェクト
  • Python)Webフレームワーク: Viewなど一部の処理を書くだけでWebアプリケーションが作れるPythonパッケージ
    • ユーザーの書いたViewなどを読み込んで、WSGIアプリケーションとして動作する

このように、WSGIという仕様でPython製Webアプリケーションは作られています。 Python製のWebフレームワークでWebアプリケーションを作ったときは、WSGIサーバーで動作させれば良いと覚えておきましょう。