Next.js(React),Go kit(Golang)で「SENRYU」を個人開発した

今回はじめて個人開発でアプリを作りました!!今年の1月に個人開発をしようと考えてから、アプリ企画・技術選定をして、開発途中で作るアプリを変えたりと色々と迷走しましたが、なんとか一区切りつきました!!(8か月ぐらいかかるなんてチンタラやってたなあ(笑)) 開発したアプリや今まで考えていたことなどをまとめます。 アプリ概要 川柳を共有することができるSNSアプリ「SENRYU」を開発しました。 機能 ログイン ユーザー登録 ログアウト 川柳一覧表示 マイ川柳一覧表示 川柳投稿 フロントエンド Next.js(React) フロントエンドにはNext.jsを利用しました。TypeScriptを使ってみたくて、TypeScriptと相性がいいReactを選択して、最近話題のNext.jsにしようと決めました。 Next.jsはルーティング設定が楽だし、SSG, SSR, SPAをページごとに設定できて便利だしと使って良かったなと思っています。ただ、認証はFirebaseやNextAuth.jsを利用して他のSNSアカウントとかでログインする実装にするのが楽だと感じました。 Material-UI ReactのUIコンポーネントライブラリであるMaterial-UIを利用してUIの基礎を作りました。簡単に見た目を整えることができるので、とても便利です。 styled-components Material-UIの見た目を調整したい時にCCS in JSのstyled-componentsを利用しました。TypeScript内でCSSを書けるので普段CSSとかを書かない僕には使いやすかったです。 バックエンド Go kit(Golang) 個人的にGolangを利用したかったのとマイクロサービス構成でアプリを作ってみたいという理由からGo kitを利用しました。使ってみた感想としてあまり日本語のドキュメントとかなく調べるのが大変でしたが、Golangにはホットリロードがあってコンパイルが速く言語に慣れれば開発スピードが上がりそうだなと思いました。 データベース MongoDB NoSQLを利用したことがなかったので今回利用しました。MongoDBの基礎的な知識を身につけることはできましたが、RDBMSよりもNoSQLを利用するメリットがあんまりわからなかったです。 開発環境 Docker マイクロサービス構成でアプリ開発をしていたので、それぞれのサービス毎にコンテナを作成しました。ローカルでDockerコンテナを立てて開発するときはVSCodeのRemote Containerが非常に便利でした。ぜひ使ってみてほしいです。 対象リポジトリ senryu-frontend senryu-user senryu-post 記事を書くまでの経緯 元々、今年の1月に他のサービス開発を考えていました。技術選定の時には Next.js(React) TypeScript Go kit(Golang) MongoDB Docker Github Actions AWS K8s マイクロサービス でアプリを開発してリリースをしようと思っていました。せっかくの個人開発だし勉強もかねて挑戦してやる!っていう気持ちで技術選定をしましたが、今思うとDocker以外はほぼ経験がなかったのでめちゃくちゃ無謀だったなと思います。(笑) そんな感じで技術選定をしてから要件や仕様決めて開発を始めましたが、わからないことが多すぎで全然進捗がなかったです。。亀の足のような遅さでしたがなんとか進めていた 4月頃か5月頃に気づいてしまいました。 「クラウドでK8s使うと金けっこうかかるやんけ!」 今思うと当たり前だし、調査不足すぎだよ自分。。ということがあり、最初に作りたかったサービスは世にリリースするのが厳しいなと思いましたが、せっかくある程度までは勉強して作っていたので、違うサービスとして開発をしてGithubで公開してポートフォリオ的な感じにしようと決めました。 といった経緯で今に至ります。結果的には個人開発したアプリをリリースすることはできませんでしたが、Next.jsとGolangを学べたり個人開発の雰囲気を味わえたので良かったです。 最後に 個人開発はすべてを自分で考えないといけないので、とても大変ですが技術選定や作業の進め方など誰からも指図されずに好きなようにできるので、楽しいし学びが多いですね。

September 20, 2020 · 1 min · 60 words · Yu

Next.jsのgetServerSidePropsでリダイレクトをする

勉強用にNext.jsで個人開発をしていて、cookieに値がない時トップ画面にリダイレクトする実装をしたかったのですが、参考にできる情報が少なかったので記事にしました。 リダイレクト方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { parseCookies } from "nookies"; import { GetServerSideProps } from "next"; // ... export const getServerSideProps: GetServerSideProps = async (context) => { const cookies = parseCookies(context); const userId = typeof cookies.userId === "undefined" ? "" : cookies.userId; if (userId === "") { context.res.writeHead(302, { Location: "/" }); context.res.end(); } return { props: {}, }; }; cookieにuserIdを仕込んでいて、userIdがなかったらログインしていないとみなしてトップ画面に戻す実装をしました。...

September 13, 2020 · 1 min · 86 words · Yu

「React Hook Form」でフォームを簡単に作る

Next.js(React)でログイン機能を実装していて、フォーム作成に苦戦していました。 そもそも、Reactを全然理解していないので、フォームの値はどうやって取得すればいいのか?みたいなところからわかりませんでした。 今回はReact+TypeScriptでフォームを作成するのにReact Hook Formがとても便利だったので、紹介します。 React Hook Formとは 公式サイトを見ると「高性能で柔軟かつ拡張可能な使いやすいフォームバリデーションライブラリ」らしいです。 詳細は以下公式サイトを見てください。 React Hook Form さっそく実装をする まずはReact Hook Formをインストールします。 以下コマンドをプロジェクト配下で実行します。 npm install react-hook-form インストールしたら、importしてフォームの値をサポートするためのFormData型を作成します。 import { useForm } from "react-hook-form"; type FormData = { username: string; password: string; }; 今回はログイン用のフォームを作成するために、string型のusernameとpasswordを用意しました。 次に、useFormを使ってフォーム作成に必要なメソッドを受け取ります。 import { useForm } from "react-hook-form"; type FormData = { username: string; password: string; }; export default function Login() { const { register, handleSubmit, watch, errors } = useForm<FormData>(); } useForm<FormData>()のように書いてフォームで使う型を設定できます。 constで定義されているメソッドについては以下にまとめました。...

May 26, 2020 · 1 min · 187 words · Yu

Go製APIから「fetch」するのにハマった

Next.js(React)+Goで個人開発をしていて、FetchAPIを利用してGoでローカル環境にたてたAPIをNext.jsで呼び出す際に、値が取れずにはまりました。 今回はどうやって解消したのか記事にしました。 今回発生したエラー Next.jsでfetchを使ってPOSTした際に、以下のようなエラーが発生。 Error serializing `.postData` returned from `getServerSideProps` in "/posts/get-api". Reason: `object` ("[object Promise]") cannot be serialized as JSON. Please only return JSON serializable data types. ようわからんけど、APIから値が取れてないみたいでした。 Next.jsからfetchする際のコードは以下のようにしていました。 export const getServerSideProps: GetServerSideProps = async () => { const url = "http://localhost:8080/login"; ← APIはローカルの8080番ポートにたてていました。 let postData = {}; await fetch(url, { method: "POST", cache: "no-cache", headers: { "Content-Type": "application/json charset=utf-8", }, body: JSON.stringify({ username: "yagiyu", password: "miran" }), })....

May 19, 2020 · 2 min · 217 words · Yu

React + Go + MongoDBの環境をDocker Composeで作成した

現在、勉強がてら個人開発をしていて、せっかくの個人開発なので、今までさわったことがないReact, Go, MongoDBでwebアプリを作ります。 その最初の段階として、Docker Composeを使って環境構築を進めます。 Reactの環境構築 今回の開発では、プロジェクト配下をこんな感じにしています。 プロジェクト ├── backend ├── frontend Reactはfrontend配下に構築します。 Dockerfileの作成 DockerfileにDocker上で起動させるコンテナの構成情報を書きます。 frontend配下に以下内容で作成します。 FROM node:13.12.0-alpine3.10 WORKDIR /usr/src/app 1行目にはコンテナのDockerイメージ、2行目にはコンテナ内の作業ディレクトリを記載しています。 alpineはAlpine Linuxのことで、必要最低限の構成がされているおかげで、Dockerイメージの軽量化を図ることができます。 docker-compose.ymlの作成 docker-compose.ymlで複数のコンテナをまとめて起動することができます。拡張子は「.yml」「.yaml」どちらでも動きます。 どっちかに統一してくれればいいのに。 プロジェクト配下に以下内容で作成します。 version: '3' services: node: build: context: ./frontend dockerfile: Dockerfile volumes: - ./frontend:/usr/src/app command: sh -c "yarn start" ports: - "3000:3000" volumesではコンテナ内のusr/src/appをfrontendに永続化させます。 portsでは外部の3000ポートとコンテナ内の3000ポートをつなげています。ローカル環境ではlocalhost:3000でアクセスができるようになります。 Dockerイメージのビルド docker-compose.ymlのある階層で以下コマンドを叩きます。 docker-compose build Building node Step 1/2 : FROM node:13.12.0-alpine3.10 ---> b529a862f234 Step 2/2 : WORKDIR /usr/src/app ---> Using cache ---> b753b92fbf97 Successfully built b753b92fbf97 Successfully tagged プロジェクト名_node:latest 上記のような表示がされ、ビルドすることができます。...

April 11, 2020 · 3 min · 522 words · Yu