OmniAICreator/Qiita-1.07M huggingface dataset:
CSRFについて

# はじめに
この記事は[Webの基礎をおさらいカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/basic_review)です。
このカレンダーでは、なんとなくわかった気になっている、Webの知識をおさらいするカレンダーです。
興味をもし持ってくださった方は、購読いただけると嬉しいです！

## CSRF(Cross Site Request Forgeries)とは
CSRFとはWebアプリケーションの脆弱性を使ったセキュリティ攻撃の一種を指し、
日本語に直すと、サイトを横断したリクエストの偽装ということになります。

具体的な状況で言うと、
掲示板やメールなどに記載された悪意のあるURLを開いた際に、
ユーザーの意図しないリクエストを標的となるWebサービスに送信してしまう攻撃です。

別のサイトなどから、攻撃対象のサイトに対して、横断的に偽装したリクエストを飛ばしているからCSRFというわけです。

また、よく聞くセキュリティ攻撃にXSSというのがあり、そちらと混同する方もいるかと思いますが、
XSSはユーザーのブラウザで不正な操作が行われるのに対し、CSRFはWebサーバー側で不正な操作が行われるというのを意識しておきましょう。

## 被害
具体的に発生する被害は以下のような例です。

* 掲示板やSNSでの不正な書き込み
* 商品の不正購入
* 金融サービスでの不正な送金

なぜ、このような被害が起きるのかというと、Webサーバー側で、不特定多数の外部からのリクエストを許可してしまっているからです。

例えば、ログインして投稿するような掲示板では、
識別されたユーザーが文字列を入力して投稿ボタンを押すことで初めて投稿がされるため、
他の人が自分のアカウントで投稿するには、ログイン情報を知る以外に方法がないように思えます。
しかし、この投稿ボタンを押したときのリクエストを、別のサイトから行うようにして、偽装リクエストを送ることで、
その人のアカウントから投稿されたように見せることができます。

過去、CSRFによる誤認逮捕などもあったため、不審なリンクは踏まないようにしましょう。

 ## 対策
別のサイトからのリクエストを行えないようにすることが対策となります。

* CSRFトークンを利用する
    * 外部サイトには特定できない、ワンタイムトークンを使用する
        * ワンタイムトークンを発行しセッションに格納する
        * フォーム送信ページにhiddenで発行したトークンを埋め込む。
        * 送信されたトークンとセッションに格納されたトークンが一致するかを確認する
* リファラーまたはオリジンを確認する
    * どこのサイトからリクエストが来たのかを識別し、外部サイトであれば遮断する。
* セッション用CookieにSameSite属性を使用する
    * SameSite属性を使用しておけば、Cookieに保存されているセッション情報は同じサイト内でしか使えなくなります。

 
# まとめ
以上、CSRFについての説明でした。
セキュリティに対しての知見を正しく理解して、正しい対策を行えるようにしていきましょう！

[Webの基礎をおさらいカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/basic_review)でした。
興味をもし持ってくださった方は、購読いただけると嬉しいです！


## 参考文献
[IPA 安全なウェブサイトの作り方 - 1.6 CSRF（クロスサイト・リクエスト・フォージェリ）](https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_6.html)
[これで完璧！今さら振り返る CSRF 対策と同一オリジンポリシーの基礎](https://qiita.com/mpyw/items/0595f07736cfa5b1f50c)
個人的docker composeおすすめtips6選

(2024/06/21追記)
**本記事のアップデート版を[弊社技術ブログに投稿しました](https://future-architect.github.io/articles/20240620a/)。**
Tipsの追加に加え、既存Tipsの内容も更新していますので、よろしければご確認ください。

## はじめに
皆さん、docker composeを利用しているでしょうか？
複数のdockerコンテナをまとめて立ち上げたり、環境変数を定義できたり便利ですよね。
今回はある程度docker composeを利用している方向けに私が便利、便利そうと感じたdocker composeの機能を挙げてみました。

## docker compose cli v2を利用
`docker-compose`ではなく [docker compose](https://matsuand.github.io/docs.docker.jp.onthefly/compose/cli-command/)コマンドも利用可能になってます。
Docker Desktopでは v3.4.0から利用可能で、基本的にはコマンドの互換性あります。

## Docker image名やコンテナ名のプレフィックスをディレクトリ名から変更する
通常は `${ディレクトリ名}_${サービス名}`でイメージが作成されます。
環境変数`COMPOSE_PROJECT_NAME`でプロジェクト名を指定することにより
`${プロジェクト名}_${サービス名}`にイメージ名を変更可能です。
個人的なおすすめは`docker-compose.yaml`と同一ディレクトリに `.env`ファイルに追加することです。

- 例: `sample_${サービス名}`でイメージを作成したい場合
```bash:.env
COMPOSE_PROJECT_NAME=sample
```

`--project ${プロジェクト名}`を指定することによりコマンドライン引数でも指定可能です。

```bash
docker compose build --project ${project名}
```

## ヘルスチェックの設定
Dockerfileでも指定できますが、[docker-compose.ymlでも指定可能](https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck)です。
コンテナに対しコマンドを実行し終了コードなどによりヘルスチェックができます。
ヘルスチェックを利用することで依存関係の設定、サービス完了まで待機でサービスが `healthy`になるまで待機することが可能です。

```yaml:docker-compose.yml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3
  start_period: 40s
```

## 依存関係の設定
以前はコンテナの依存関係しか指定できませんでしたが、docker compose2.1からサービスがhealthyになった後に起動する、正常終了したあとに実行するなど、より[高度な依存関係を定義できるようになりました](https://docs.docker.jp/compose/compose-file/compose-file-v2.html#depends-on)。
使用可能な条件は以下
- service_started: 依存するサービス開始まで待機。(ステータスは問わない)
- service_healthy: 依存するサービスが `healthy`になるまで待機
- service_completed_successfully: 依存するサービスが正常終了するまで待機

```yaml:docker-compose.yml
version: "2.4"
services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  redis:
    image: redis
  db:
    image: postgres
    healthcheck:
      test: "exit 0"
```

## サービス完了まで待機
`docker compose up`に`--wait`オプションを利用することで、ヘルスチェックが設定されたサービスが定常状態になるまで待機することが可能です。
(執筆時点では`--wait`オプションは[ドキュメントに記載されていません](https://docs.docker.jp/engine/reference/commandline/compose_up.html)が)
以前はワンショットのサービスには `--wait`が効かないバグがありましたが[v2.7.0で修正](https://docs.docker.com/compose/release-notes/#270)されたようです。

## サービスをグループ化
[profiles](https://docs.docker.com/compose/profiles/)という機能を利用し、複数のサービスをまとめて起動・終了などをすることが可能です。
以前から`depends_on`で依存関係を指定することで依存したサービスをまとめて立ち上げることができていましたが、profilesによって依存関係がないサービスもまとめて立ち上げることが可能になりました。

```yaml:docker-compose.yml
version: "3.9"
services:
  web:
    image: web

  mock-backend:
    image: backend
    profiles: ["dev"]
    depends_on:
      - db

  db:
    image: mysql
    profiles: ["dev"]

  phpmyadmin:
    image: phpmyadmin
    profiles: ["debug"]
    depends_on:
      - db
```

```bash
docker compose --profile dev up
```

## おわりに
本記事により皆さまのdocker composeライフが少しでも豊かなものになれば幸いです。
JavaScript演算子「??」

演算子「??」------ first-defined
```javascript
let temp = a ?? b; //左変数がnullかundefinedじゃない場合，temp = a. 逆の場合temp = b

//上式は以下と同じ意味:
let temp = (a != null && a != undefined) ? a : b;
```
演算子「||」との違い 
「??」: null　と　undefined　が判断基準．
「||」: true と false が判断基準．
例：
```javascript
temp = false ?? 100;   //temp = false
temp = "" ?? 100;   //temp = ""
temp = 0 ?? 100;   //temp = 0
temp = undefined ?? 100; //temp = 100
temp = null ?? 100; //temp = 100

temp = false || 100;  //temp = 100
temp = "" || 100;   //temp = 100
temp = 0 || 100;   //temp = 100
temp = undefined || 100; //temp = 100
temp = null || 100; //temp = 100
```
例では，""と0がJavaScriptの自動型変換により，falseとして扱われる．
leetcode5 を解いてみた

# 方針
自分で1回はプロセスを考える。解けなくてもOK。
解けなかったときは、振り返ることが可能な程度まで言語化する。
※考え方おかしくない？というのがあればご指摘くださいまし。
※解けなかった、苦戦したものを記事にする。

# 問題紹介

問題は以下URL参照

https://leetcode.com/problems/longest-palindromic-substring/description/

## 最初の考え
- スマートな解法わかんないっぴ...
- とりあえず愚直にやってみるっぴ...

``` 初回.py
class Solution:
    def longestPalindrome(self, s: str) -> str:
        tmp = []
        res = ""
        length = 0

        for i in range(len(s)):
            tmp = []

            for j in range(i,len(s)):
                tmp.append(s[j])
                reversed_tmp = list(reversed(tmp))
                if tmp == reversed_tmp and length < len(tmp):
                    length = len(tmp)
                    res = ''.join(tmp) 

        return res
```

## 思考中
- 案の定時間制限に引っかかった
- submitするたびに落ちるテストケースが変わるんだがなんぞや。実行時間ブレかな(´・ω・｀)
- 配列操作間引いたらもうちょいマシになるのかな？
    - とりあえず文字列でやってみたらどれぐらい良化するか見てみる。

``` second_try.py
class Solution:
    def longestPalindrome(self, s: str) -> str:
        tmp = ""
        res = ""
        length = 0

        for i in range(len(s)):
            tmp = "" #init for loop

            for j in range(i,len(s)):
                tmp = s[i:j+1]
                reversed_s = tmp[::-1]
                
                if tmp == reversed_s and length < len(tmp):
                    length = len(tmp)
                    res = tmp 

        return res
```
## 思考中2
- テストケース1/3 ⇨ 2/3通るようになったので速度は向上した(当たり前)
- これ以上はちゃんとアルゴリズム考えないとダメそう。
- 後は余分なサーチしてる部分を削って通るかどうかだな。

``` third_try.py
class Solution:
    def longestPalindrome(self, s: str) -> str:
        tmp = ""
        res = ""
        length = 0

        for i in range(len(s)):
            tmp = "" 
            if len(s)-i < length and res != 0:　　#add
                return res

            for j in range(i,len(s)):
                tmp = s[i:j+1]
                reversed_s = tmp[::-1]
                
                if tmp == reversed_s and length < len(tmp):
                    length = len(tmp)
                    res = tmp 

        return res
```

## 結果
third_try.pyで通ったけど実行速度ひどい...(´・ω・｀)

- solutionを見るとDPでやれるでって書いてるけどどうやったらDPでできるんだ状態(´・ω・｀)
- 文字列のど真ん中から回文をサーチしていくっていうやり方もあってなるほど...ってなった。
    - 今回通したブルートフォースよりかは計算量減りそう。

ほぼ初めてmedium解いたけど、解けるやつは解けるということがわかったのは嬉しい。
じわじわ精進します(´・ω・｀)
[JavsScript] map, find, filter, forEachの特徴と書き方 + スプレッド構文

皆さんこんにちは、
今回はJavaScriptなどでよく用いられる
配列操作の「map」「find」「filter」「forEach」の4つについて解説していきます。
また、最後に、ループ処理で要素を追加したい時に便利なスプレッド構文についても簡単に紹介します。

## 目次
[1. map関数](#1-map関数)
[2. find関数](#2-find関数)
[3. filter関数](#3-filter関数)
[4. forEach関数](#4-find関数)
[5. map関数とスプレッド構文](#5-map関数とスプレッド構文)
[6. 最後に](#6-最後に)

それでは早速見ていきましょう。
それぞれのループ関数で使用するデータは以下を前提としています。
```javascript:
const data = ["オレンジ", "リンゴ", "キウイ", "モモ", "オレンジ"];
```

## 1. map関数
- 特徴 
    - ```map```はすべての要素に対して関数を一度ずつ実行し、戻り値(return)からなる配列を新たに生成する
    - ```filter```と類似しているが、基本的に実行前と後で新しい配列の数は変わらない
    - 生成された配列の値には関数実行時の戻り値(return)が格納される

- 使用例
```javascript:
const map = data.map((item) => {
  return item;
});
console.log(map)
// 出力結果
// ▶(5) ["オレンジ", "リンゴ", "キウイ", "モモ", "オレンジ"]
``` 


## 2. find関数
- 特徴 
    - ```find```は指定した条件の内、**該当する最初の要素**を対象の配列から返します。
    - 該当の値は返り値に格納される

- 使用例
```javascript:
const find = data.find((item) => {
  return item === "オレンジ";
});
console.log(find)
// 出力結果
// オレンジ 
``` 

## 3. filter関数
- 特徴 
    - ```filter```は```find```と若干異なり、指定した条件の内、**該当するすべての要素**を対象の配列から返します。
    - 該当の値は返り値に格納される

- 使用例
```javascript:
const filter = data.filter((item) => {
  return item === "オレンジ";
});
console.log(filter)
// 出力結果
// ▶(2) ["オレンジ", "オレンジ"]
``` 

## 4. forEach関数
- 特徴 
    - ```forEach```は指定した配列の中身を一つずつ出力します。
    - ほかのループ処理の動きと異なり**返り値がない**ので以下のサンプルコードのように```undefined```が返されます。
    - **break, continue**などの中断/スキップ処理も行えません。

- 使用例
```javascript:
const forEach = data.forEach((item) => {
  return item;
});
console.log(forEach)
// 出力結果
// undefined
``` 

## 5. map関数とスプレッド構文
スプレッド構文とは何ぞやって話なんですが、
よく配列操作や反復可能オブジェクトに対して利用する「...」(ドット3つ)のやつです。
最初見た時は訳が分からず、検索の仕方もいまいちわからないので大変でした(笑)

実はmap関数への要素追加などにスプレッド構文を使うと効率が良いです。
[公式の解説](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)ではスプレッド構文を使って数値データの合計値を求めていますね。
使用例は以下のようになります。
```javascript
const data = [
  { name: "リンゴ" },
  { name: "レモン" }, 
  { name: "オレンジ" }
];

const map_addCategory = data.map((item) => {
  return {
    ...item,
    "category": "フルーツ"
  };
});

console.log(map_addCategory)
// ▼(3) [Object, Object, Object]
//   0: Object
//     name: "リンゴ"
//     category: "フルーツ" ← カテゴリが追加されている
//   1: Object
//     name: "レモン"
//     category: "フルーツ" ← カテゴリが追加されている
//   2: Object
//     name: "オレンジ"
//     category: "フルーツ" ← カテゴリが追加されている
```
各要素にcategoryの値は追加されているのがわかります。
このように各データに対して要素を追加したい時にはスプレッド構文を使用するのがおすすめです。


## 6. 最後に
いかがだったでしょうか。
私はここ一年の業務でこれらの関数を扱う機会が非常に多く、年始から比べ、かなり使い方に慣れました。
また、今回は```Object```の型で行いましたが、
配列でも```temp=[...item, "追加したい値"]```といった書き方で追加が可能です。

少しでも参考になれば幸いです。
もし記載事項で不備等ありましたらコメントいただけると幸いです。

それではまた次回…
【Do'er】2022年の振り返り

この記事は，[Do'er Advent Calender](https://qiita.com/advent-calendar/2022/doer) の25日目の記事です．

こんにちは！
Do'er 代表のかずやんです．

この記事では，今年設立した同志社大学の学生エンジニア団体である Do'er の活動について振り返りたいと思います．

# サークル設立と今
僕自身がエンジニアとしてインターンに参加させていただいたり，ハッカソンなどに出場する中で，同じ大学のエンジニアと出会うことがほとんどありませんでした．
また，技術について学んだり，仲間との開発経験を得る機会がないために，エンジニアになることを諦めてしまっている学生がいるという現状を変えたいという思いがありました．

当初は同じ研究室のメンバーの @mahiro72 や昔インターンで出会った @wafuwafu13 と一緒に細々とやる予定でした．
幸いにも素晴らしいメンバーの方々が集まっていただき，当初6人だったメンバーは今では40人以上となり，盛り上げてくださってるメンバーの方々には感謝してもしきれません．

今となっては，ハッカソンで多数受賞したり，競プロにおいてはICPC本戦に出場したり，データ分析コンペでメダルを取ったりと，充実した活動ができています．

# 活動実績
ここでは，Do'er の1年間の活動を振り返りたいと思います．
学生団体の活動の一例として見ていただけると幸いです．
受賞メンバーの名前に関してはここでは省略させていただきます．

## -4月
新年度ということもあり，メンバーが一気に増えました．
この時期くらいで20人近くに達していました．

### イベント
- サークル設立
- 部内顔合わせ会
- サークルHP 開発・公開
- 部内LT会

### 実績
- 技育祭登壇
- 42Tokyo Piscine 2名合格
- 42HoursTuningTheBackend 1位
- メンバーがAtCoderヒューリスティック青色【上位5％】昇格

## 5，6月
メンター制度やDiscordチャンネル整理など，部内制度を中心に整備しました．
また，オフラインイベントを開催し，オンライン上で関わっていたメンバーと関わる機会があり、盛り上がっていました．

### イベント
- 部内オフラインイベント開催
- 技育博参加

### 実績
- 技育CAMP vol4 努力賞 おかしおみくじ
- Nishika 中古マンション価格予測 9位

## 7，8月
ハッカソンに参加してチーム開発をする文化が根付いてきました．
また，競プロ合宿など，競プロ'erたちが切磋琢磨していました．

### イベント
- 競プロ合宿
- オフライン交流会

### 実績
-  技育CAMP vol5 最優秀賞 MeetHack
-  SPAJAM 第１回予選 優秀賞
-  RECRUIT 日本橋ハーフマラソン学生入賞 2022 夏
-  メンバーがAtCoderアルゴリズム青色【上位5％】昇格

## 9，10月
技育展に2作品を出展したり，チーム開発に慣れてきたメンバーがなれないメンバーをリードする一面もありました．
また，自分の推しの技術を紹介したり，データ分析コンペの振り返り会などを開催しました．

### イベント
- 交流会
- オンライン交流会
- オンライン競プロ合宿
- インフラ周り触る会
- Nishika 中古マンション価格予測 感想LT会
- F#講座
- 株式会社サイバーエージェント主催 関西学生団体交流イベント

### 実績
- 技育展2022 登壇 DITA
- 技育展2022 優秀賞 MeetHack
- sansan trigger 2位
- JPHACKS Best Hacking Sprint Award(Fブロック1位), Hacking Sprint Block Sponsor Award(シグマ賞)

## 11，12月
ユニバ会という良い意味でエンジニアらしからぬ（？）イベント発生していたり，学生らしい充実したイベントが開催されていました．

### イベント
- ユニバ会
- 忘年会・振り返りLT会（予定）

### 実績
- JPHACKS Finalist Award
- JPHACKS Audience 2位, 審査委員特別賞, Innovator認定, Award Day Sponsor Award (サントリー賞, シグマ賞, Jストリーム 賞)
- 技育CAMP vol9 努力賞 消えちゃっと
- Nishika ヘイトスピーチ検出 銀メダル

## まとめ
設立1年目はメンバーのお陰でとても充実した1年となりました．
来年以降も，より良いエンジニア育成の環境づくりに邁進していきたいと思います．

最後に，今年1年間弊部に関わってくださったメンバーと関係の皆様，本当にありがとうございました！
Vue Flow触ってみた

# はじめに

組織図のようなものを作成できるツールを探していたところ、
[Vue Flow](https://vueflow.dev/)を発見。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/bf123cbe-42f0-61f6-d073-f56bee77f86f.png)

早速使ってみました。

# 導入

vue-flowの本体と、各コンポーネントを必要に応じてインストール

```bash
// vue-flow本体
yarn add @vue-flow/core
// 各コンポーネント
yarn add @vue-flow/background @vue-flow/controls @vue-flow/core @vue-flow/minimap @vue-flow/node-toolbar
```

# 用語

## Nodeとは

こいつのこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/7492d713-3aa2-09be-42bf-9721792a011b.png)

typeを指定でき、`input`及び`output`を指定できる。

### `type: input`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/58d6af9e-fc59-2e7a-17bb-0a5aa78cb248.png)

このように下方向にだけ接続できる。
スタートで使うイメージ。

### `type: output`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/89447f6b-a4d1-f7dc-2af8-955058e0e29a.png)

inputの反対で、上方向にだけ接続できる。
ゴールで使うイメージ。

また、`label`で指定すると、文字が入れられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/a122604c-f694-692f-b8a5-b688d3a194c5.png)


## Edgeとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/e2ec8ace-7bc2-8976-a1a1-7771749369e4.png)

こいつのこと。

![animate.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/a72c8601-dd36-0794-1abb-f75325491bab.gif)

`animated: true`でアニメーションを付けたり、

`markerEnd: ○○`で終点を変えたりすることができる。

また、`label`で指定すると、文字が入れられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/612c7d74-0629-38f7-9a3f-7ff22abcac7e.png)

# 使い方

`VueFlow`コンポーネントに`node`や`edge`情報が入ったオブジェクトを渡してあげるだけ。


```vue
<script setup lang="ts">
import { VueFlow  } from '@vue-flow/core'
import { ref } from 'vue'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'

const elements = ref([
  { id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 5 } },
  { id: '2', label: 'Node 2', position: { x: 100, y: 100 }, },
  { id: '3', label: 'Node 3', position: { x: 400, y: 100 } },
  { id: '4', type: 'output', label: 'Node 4', position: { x: 400, y: 200 } },
  { id: 'e1-3', source: '1', target: '3' },
  { id: 'e1-2', source: '1', target: '2', animated: true },
])
</script>
<template>
  <VueFlow v-model="elements" />
</template>
```

![flow.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/8efdc924-2e87-ea44-57a3-7c62071b4183.gif)

参考) 公式`BasicExample`


紹介したNodeの`type`や、Edgeの`animated`以外にも様々なPropsが用意されているので、
いろいろなことができそうですね
OCIからの外部接続について

# はじめに
今回は、OCIからの外部接続について扱っていきます。
パブリックインターネットでの接続も可能ですが、通信速度やセキュリティ面で懸念があります。
OCIが提供している通信方法であるSite-to-Site VPNとFastConnectについて触れていきます。

# Site-to-Site VPN
そこでまず、Site-to-Site VPNの使用を検討します。

◆特徴
・OCIが提供する無料で冗長性のあるVPNトンネル。
・業界標準のIPSec暗号化を適用。
・オンプレミスシステムには、CPEの設定が必要。

通常POCではSite-to-Site VPNを使用し、必要に応じてFastConnectに移行していきます。
とりあえず、使ってみたい場合に最適です。

# FastConnect

専用線を使用してより安定した回線を確保したい場合はFastConnectを使用します。

◆特徴
・ポート速度は1Gbps・10Gbpsから選べる（速い！）
・受信、送信データの転送には料金がかからない
・BGPプロトコルを利用
・専用線を使うため、遅延の影響を受けづらい。

# 参考ページ
・Site-to-Site VPN
  https://docs.oracle.com/ja-jp/iaas/Content/Network/Tasks/overviewIPsec.htm

・FastConnect
  https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/fastconnectoverview.htm
  https://blogs.techvan.co.jp/oci/2022/01/26/oci-fastconnect/

# さいごに
今回はOCI独自の通信について扱いました。
自分のような初心者でも拒否反応が出ないような投稿を続けてまいります。
次回、またよろしくお願いします。
20万人が利用しているサービスのJSONシリアライザをAlbaに置き換えた話

# TL;DR
NewRelic transactions
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227205/89c86245-5fe4-f1e3-80f6-ded8500a219d.png)

# はじめに
株式会社KINECAでエンタメマッチングサービスを運営している@ryosk7です。
この記事はRuby on Rails Advent Calendar 2022の23日目の記事です。

# Albaって？
https://github.com/okuramasafumi/alba

AlbaはRuby製のJSONシリアライザです。
Ruby on Rails Advent Calendar 2022 14日目の記事にも、ちょうど作成者の[@okuramasafumi](https://twitter.com/okuramasafumi)さんが記事を執筆してくださってます。

https://qiita.com/okuramasafumi/items/b52c9c9e5d3e7cdfa371

Albaの特徴として、他シリアライザーよりも高速な点が挙げられます。

### ベンチマーク
[参考](https://github.com/okuramasafumi/alba/tree/main/benchmark)

```
Comparison:
               panko:      283.8 i/s
       turbostreamer:      102.9 i/s - 2.76x  (± 0.00) slower
                alba:      102.4 i/s - 2.77x  (± 0.00) slower
         alba_inline:       98.7 i/s - 2.87x  (± 0.00) slower
         jserializer:       93.3 i/s - 3.04x  (± 0.00) slower
     fast_serializer:       60.1 i/s - 4.73x  (± 0.00) slower
         blueprinter:       53.8 i/s - 5.28x  (± 0.00) slower
               rails:       37.1 i/s - 7.65x  (± 0.00) slower
            jbuilder:       37.1 i/s - 7.66x  (± 0.00) slower
           primalize:       31.2 i/s - 9.08x  (± 0.00) slower
 jsonapi_same_format:       28.3 i/s - 10.03x  (± 0.00) slower
       representable:       27.8 i/s - 10.23x  (± 0.00) slower
             jsonapi:       27.5 i/s - 10.34x  (± 0.00) slower
          simple_ams:       16.9 i/s - 16.75x  (± 0.00) slower
                 ams:        8.3 i/s - 34.36x  (± 0.00) slower
```

こちらの記事にも書かれていますが、pankoはCで拡張されているため、純粋なRubyで書かれているAlbaはかなり健闘しているなと感じました。

https://okuramasafumi.hatenablog.jp/entry/2021/12/03/144055

弊社では主にjbuilderを使っていますが、こうやってベンチマークでみると、差が明らかです。(現在はOjを使って多少早くしています。)

Albaの特徴は他にも、拡張性の高さや、レイアウトという機能もあるので、後日試してみようと思います。

そんな、速さに特徴のあるAlbaですが、実際に本番運用で試している記事が見当たらなかったので、サービスの中でも重たいAPIに対して、
jbuilderからAlbaに置き換えてみました。
実際にリリース後、NewRelicで計測してみたので、この記事で公開します。
現在jbuilderを使っている方、速度改善を試みている方、Albaが気になっている方の参考になればと思います。

# 計測

![スクリーンショット 2022-12-23 15.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227205/f380d2b7-b9e2-ca5e-9f4d-ed301ef5c25d.png)

結果がすごくわかりやすい！！
赤枠がリリースタイミングですが、リリースした後、大体半分くらいまで下がっています。
やはり、partialがボトルネックになっており、Albaに変えたことで改善されました。
ただし、APIの処理として巻き込まれてしまったので、NewRelic上では見辛くなってしまいました。

# まとめ
Albaを導入したことにより、劇的な速度改善に繋がりました。
今回は試しに1個のAPIに絞って変更しましたが、徐々に広げていき全体的な速度改善に繋げていこうと思います。
CP4DやCP4DaaSのWatson Studioでファイルのダウンロードを禁止する

CP4DやCP4DaaSのWatson Studioでファイルのダウンロードを禁止したいことがあります。そのためにはプロジェクトを作る際に「機密のマークをつける」にチェックを付けます。

■CP4Dの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/151fcea7-29a6-3187-4396-a7c14ced1c52.png)

■CP4DaaSの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e11a2897-93c2-d4f7-b2e0-783b61482cd6.png)

このプロジェクト内の資産でダウンロードのメニューが出なくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/5f1a6eab-644d-a05a-7485-e38df9aa3ec7.png)

プロジェクトのエクスポートをしようとしても、中身が空になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cfe40094-63bb-a675-5ff0-3cfbecd77bfe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ebec52dd-610a-8309-790f-b6476b9aaf05.png)

* テスト環境
    * CP4D 4.5.3
    * CP4DaaS
enebularでnode-red その10

# 概要
enebularでnode-redやってみる。
練習問題やってみた。

# 練習問題
生httpが見たい。

# フロー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a61c05c2-3e90-c1c3-eb47-f1e462ba10a5.png)


```
[{"id":"bba3689b8172b78f","type":"http in","z":"51e5f3dfc3ba1f13","name":"","url":"/nama","method":"get","upload":false,"swaggerDoc":"","x":180,"y":560,"wires":[["aa64ccd7dcdc9b67"]]},{"id":"aa64ccd7dcdc9b67","type":"function","z":"51e5f3dfc3ba1f13","name":"","func":"msg.payload = JSON.stringify(msg.req.headers);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":560,"wires":[["a09f27ad4bafd908"]]},{"id":"a09f27ad4bafd908","type":"template","z":"51e5f3dfc3ba1f13","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<textarea rows=\"30\" cols=\"90\">\n    {{payload}}\n</textarea>\n","output":"str","x":500,"y":560,"wires":[["1d20c0a703e36e29"]]},{"id":"1d20c0a703e36e29","type":"http response","z":"51e5f3dfc3ba1f13","name":"","statusCode":"","headers":{},"x":670,"y":560,"wires":[]}]
```

# 実行結果

```
    {"host":"ev2-prod-node-red-d2dbd1f0-936.herokuapp.com","connection":"close","cache-control":"max-age=0","sec-ch-ua":"\"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"108\", \"Google Chrome\";v=\"108\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","sec-fetch-site":"none","sec-fetch-mode":"navigate","sec-fetch-user":"?1","sec-fetch-dest":"document","accept-encoding":"gzip, deflate, br","accept-language":"ja,en-US;q=0.9,en;q=0.8","cookie":"connect.sid=s%3AtltbzEIGg1fO6-34R8p9VrAZVV5bZ4P8.iS2uRekwfRETNDp%2F%2FtFE76XilWTEGdEzDQkL02%2B0MfA","if-none-match":"W/\"766-UjXfmMXSbRz7/Ig+A/fhPl679Po\"","x-request-id":"39f27371-f63d-4339-b48d-cfda17fa328f","x-forwarded-for":"49.129.241.***","x-forwarded-proto":"https","x-forwarded-port":"443","via":"1.1 vegur","connect-time":"0","x-request-start":"1671777693771","total-route-time":"0"}

```

以上。
URI URL URNについて

# はじめに
この記事は[Webの基礎をおさらいカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/basic_review)の1日目です。
このカレンダーでは、なんとなくわかった気になっている、Webの知識をおさらいするカレンダーです。
興味をもし持ってくださった方は、購読いただけると嬉しいです！

普段よく耳にする、URI,URL,URNの違いについて説明します！

## URL(Uniform Resource Locator)について

Locatorとあるように、場所を表します。
この中だと、一番耳馴染みがある単語かと思います。

Webブラウザで、Webページを閲覧すると 下記のような場所を示す文字列を見たことがあると思います。

`https://qiita.com`

このhttpsの部分はプロトコル(通信方式)を表していて、qiita.comの部分はドメインを指しています。
つまり、https通信で、qiita.comというドメインに情報を取りに行くことを示しています。

httpsの部分は他の例だと、ftpだったりmailtoだったりが有名かと思います。

どこにコンテンツがあるか、を表したものと覚えましょう。

##   URN(Uniform Resource Name)について
インターネットに存在するリソースを一意に識別するためのものです。
URLは、住所のようなもので、ドメインを引っ越しすれば、元々のドメインを指定しても(リダイレクト設定しない限り)同じコンテンツを参照はしないですが、
URNは固有名詞のように、常にそのリソースを指し示します。

例えば、図書に割り当てられているISBNコードもURNの一つの例です。

現実世界での例で言うと、図書館で、本を借りるときに、その図書館のどこにあるかを指し示すのがURLで、その本自体を指し示すのがURNです。
図書館のどこに置くかで、場所(URL)は変わってしまいますが、その本の名称(URN)自体は変わらないですよね。
(正確には、同じ本は何本も刷られているので、その本自体というよりはコンテンツとしての意味合いです)


##  URI(Uniform Resource Identifier)について
URIはURN・URLを包括した総称です。
なので、URLのことをURIといっても間違いではないですし、URNのことをURIといっても間違いではないです。


# まとめ
混同しやすいですが、略称が何の略になっているのかを考えれば分かりやすくなるかと思います！

[Webの基礎をおさらいカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/basic_review)でした。
興味をもし持ってくださった方は、購読いただけると嬉しいです！


## 参考文献
[MDN ウェブ上のリソースの識別](https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web)
【常識！？】開発・テストで使う Android Studioコマンド ４選

# はじめに <!-- h1見出し -->
<!-- 発端や概要 -->
私はアルバイトで開発、テストをしている大学生です。
ある程度の期間、開発やテストから離れると、いつもコマンドを忘れてしまい同じことをよく検索してしまいます。

そこで、備忘録としてこの記事を書くことにしました。
現役エンジニアの方からすると、常識のような知識だとは思います。
逆にこんなのあるよと教えてくださると私がとても喜びますので、コメントお待ちしております。

(アルバイトでよく使用しているAndroid Studioを例にして記述していきます)

**※文字だけではイメージしづらいので、実際にコマンドを実行しながら見ることをお勧めします！**


## １．定義元・使用先 に遷移する
***「このメソッド、どこで定義されてるんだ？見つからねえ！どんな処理してんだよ！」***
　または
***「このメソッド、どこで使用されてるんだ？変更による影響範囲がわからねえ！」***
というときに使用します。

- Windows : *[Ctrl + 左クリック] (Ctrl + B も可)*
- MacOS : *[command + 左クリック] (command + B も可)*

メソッド定義元に使用すると、使用先に遷移します。
メソッド使用先に使用すると、定義元に遷移します。

使用先が複数あるときは、下記画像のようにリスト表示されます。

![スクリーンショット 2022-12-23 14.56.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705701/61e774f8-545c-d28b-1cd4-af0862a78f85.png)

ちなみに変数やクラスなど、基本的に全てに使用できます。汎用性が高く、重宝しますね！

## ２．定義元・使用先 に遷移してから元の箇所に戻る
上記１のコマンドを使用してから、使用する前の箇所に戻るためのコマンドです
- Windows : *[Ctrl + Alt + 左右矢印キー]*
- MacOS : *[command + option + 左右矢印キー]*

これは１のコマンドとセットで使用しないと痛い目を見るので、セットで覚えましょう！

## ３．プロジェクト内で検索したい！
下記画像のように、[Ctrl + F] や [command + F]でファイル内の検索はできますが、プロジェクト全体での検索はできませんよね。
![スクリーンショット 2022-12-23 15.04.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705701/5194f5d5-d678-306d-1cdf-91a59cbfdb6f.png)


そんな時にはこのコマンドを使いましょう！
- Windows : *[Ctrl + Shift + F]*
- MacOS : *[command + Shift + F]*

下記画像のように、プロジェクト全体での検索結果をリスト表示してくれます！
![スクリーンショット 2022-12-23 15.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705701/a071e677-0963-5b73-d741-111e717edef7.png)

このコマンドを利用すると、モジュールやディレクトリを範囲として検索することも可能なので、ぜひ使用してみてください！

## ４．行数指定での遷移
あなたは今55行目を見ているとします、次に742行目を見に行きたいです。頑張ってスクロールしますか？それともスクロールバーで探しに行きますか？
いや、行数を指定してそこへ飛べばいいじゃん！ということでこのコマンドを使いましょう！
- Windows : *[Ctrl + L]*
- MacOS : *[command + L]*

下記画像のように **[行数：文字数]** で位置を指定できます。
![スクリーンショット 2022-12-23 15.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705701/3dcf2b02-6387-fbd1-1ba2-d7510d6fb647.png)

# 備考
こんな投稿を読んでからお知らせするのもなんですが、公式がショートカット集を出していたので、載せておきますね。
私もこの記事を書いている途中で初めて知ったので、許してください！
- [キーボード ショートカット  |  Android デベロッパー  |  Android Developers](https://developer.android.com/studio/intro/keyboard-shortcuts?hl=ja)



<!--
＜hタグ(#の数がhタグの数字に対応する)＞ーーーーーーーーー
#
##

＜コード表記＞ーーーーーーーーーーーーーーーーーーーーーーー
```言語名:ファイル名.拡張子
コードブロック
```
＜インライン(背景つき太字的な？)＞ーーーーーーーーーーーーー
`インライン表示`

＜取り消し線＞ーーーーーーーーーーーーーーーーーーーーーーー
~~取り消し線~~

＜箇条書き＞ーーーーーーーーーーーーーーーーーーーーーーーー
- テキスト
- テキスト

＜参考文献＞ーーーーーーーーーーーーーーーーーーーーーーーー
- [リンクテキスト](URL)
- [リンクテキスト](URL)

-->
JavaScriptの関数まとめ

# JavaScriptの関数
## はじめに
Javascriptの関数についてまとめました

JavaScriptにおいて関数の種類はいろいろな種類がある



## 関数式
関数式は関数を変数に代入して関数定義する手法。

変数の種類 変数名　＝ function (引数) {
処理を記述
}


```javascript:sample
//関数式を定義
const sample = function() {
    //処理を記述
    console.log("sample");
}
//関数式の呼び出し
sample();
//出力結果:sample
```

### アロー関数
関数式でfunctionを省略して記述する方法
関数式の
**function()を()=>に置き換えることができる**
```javascript:sample
//アロー関数の定義
const sample = () => {
    console.log("sample");
}
//アロー関数の呼び出し
sample();
//出力結果:sample
```

### 無名関数（匿名関数)
名前の通り関数名のない関数
(関数名については次の関数宣言にて説明を記述)
上記の関数式とアロー関数も無名関数の一つ


## 関数宣言

下記のfanctionの後についているsampleが関数名
function 関数名(引数) {
    処理の内容
}

```javascript:sample
//関数宣言を定義
function sample() {
    cosole.log("sample");
}
//関数宣言の呼び出し
sample();
//出力結果:sample
```

## コンストラクタ関数
コンストラクタ関数は新しいオブジェクトを生成するための設計図となる関数。
Rubyに例えるとクラスと考え方が似ている。
コンストラクタ関数は関数式でも関数宣言でも定義できるがアロー関数を用いることができない。
```javascript:sample
//コンストラクタ関数を定義
const person = function (name, age){
    //処理を記述
    console.log(`名前は${name}です。現在は${age}歳です。`);
}
//変数taroにtaroに関わる情報の入ったインスタンスを代入する。
const taro = new person("太郎", 18);
//taroを呼び出す.
taro;
//出力結果:名前は太郎です。現在は18歳です。
```

## まとめ

関数の定義の種類が多くて今も使いながら覚えている途中です。
この投稿は初心者が投稿しています。
間違えないように記述していますがもし認識のずれや間違えがあればご指摘いただけたら幸いです。
enebularでnode-red その9

# 概要
enebularでnode-redやってみる。
練習問題やってみた。

# 練習問題
クライアントのグローバルIPアドレス返せ。

# フロー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7b7a6487-7450-4048-ed70-63038b104b9f.png)


```
[{"id":"a44f4e88.31af4","type":"http in","z":"51e5f3dfc3ba1f13","name":"","url":"/ipinfo","method":"get","upload":false,"swaggerDoc":"","x":180,"y":420,"wires":[["4974a693.d4f5d8"]]},{"id":"4974a693.d4f5d8","type":"function","z":"51e5f3dfc3ba1f13","name":"ip","func":"msg.payload = msg.req.headers[\"x-forwarded-for\"];\nreturn msg;\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":420,"wires":[["9ab9fd051dbadb72"]]},{"id":"18e86d05.60ff63","type":"http response","z":"51e5f3dfc3ba1f13","name":"","statusCode":"","headers":{},"x":670,"y":420,"wires":[]},{"id":"9ab9fd051dbadb72","type":"template","z":"51e5f3dfc3ba1f13","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<h1>{{payload}}</h1>","output":"str","x":520,"y":420,"wires":[["18e86d05.60ff63"]]}]
```

# 実行結果

```
49.129.241.***
```

以上。
DevOps Center と CircleCI

[CircleCI Advent Calendar 2022](https://qiita.com/advent-calendar/2022/circleci) 23日目、今年もゆかちゃんの誕生日にお邪魔します。3年目です。ね。

今年は Salesforce + CircleCIについての軽ネタです。

---

# DevOps Centerが出てきましたが...

最近、Salesforceでは[DevOps Center](https://help.salesforce.com/s/articleView?language=ja&id=sf.devops_center_overview.htm&type=5)というものをリリースしました。これは、Salesforce上で、Salesforceの宣言的開発と、ソースコード開発とをとりもちつつ、変更・リリース管理を画面だけでやり遂げてしまうという、とても素敵なツールです。Sandboxなどの開発・テスト・ステージング環境も管理できてしまう上、上位の環境へプロモートする際にApexのテストの実行レベルも決められるので、プロモーションと同時に自動的にテストまで行えてしまう画期的、素晴らしい変更・リリース管理ツールです。

おやおや、そうなってくると、CircleCIとの連携などは過去のものなのか、もう必要ないのか...。

というとそういうわけではありません。単体テストの自動化などをまるっとやってくれるわけではないので、CircleCIなどとの連携による自動テストは必要不可欠なのです。


# でも、どうやって DevOps Centerと連携するのか...

この[DevOps Center](https://help.salesforce.com/s/articleView?language=ja&id=sf.devops_center_overview.htm&type=5)は、実はソースコードリポジトリとして GitHubを採用しています(将来的にリポジトリは増えていく予定のようです)。

したがって、これまで行ってきた Salesforce DXでのCIは活用できます。これまで通り[Salesforce Orbs](https://circleci.com/ja/integrations/salesforce/)を利用して、[CircleCI を使用した継続的インテグレーション | Salesforce DX 開発者ガイド | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_ci_circle.htm)に従って Salesforce + CircleCI による CIを今まで通り利用できます。

https://circleci.com/ja/integrations/salesforce/

# でもちょっと連携とか面倒だったりする...

まだちょっとどうなるか、先は見えてきませんが、先日のSWTTで日本に来てくれた Karen から [Out-of-the-box CI/CD automation · Issue #31 · forcedotcom/devops-center-roadmap](https://github.com/forcedotcom/devops-center-roadmap/issues/31) が投稿されています。具体的に、どの CI/CDツールと連携するのみたいなとこはわかりませんし、R&Dチームのコメントを見る限り積極的な感じは受けません。が、すでに実装されている CI/CD ツールとの連携が容易にできると、開発生産性がとても高まりますので、ここは期待しておきたいところです。

---

# 参考資料

https://qiita.com/hrk623/items/cb65b960cec671922d19

https://qiita.com/shinchit/items/516b02a1bb69e223b165
Azure Storage + Azure CDN でCORP対策を行う

## いきさつ
App ServiceでWebサイトを構築し、画像ファイルはBLOBストレージに配置した。
しかし、WebサイトのオリジンとBLOBストレージのオリジンは異なるため
「このリクエストは相手側で許可されてませんよ！」
とブラウザ側でブロックされてしまった。
最初はCORS(Cross Origin Resource Sharing)の問題だけかと思ったが
「cross-origin-resource-policyヘッダが設定されていません」
という内容だったのでこのエラーについて調べたところCORP(Cross Origin Resource Policy)が該当するらしい。

https://zenn.dev/toukairin/articles/b4bfc6ee35056f

## 対策方法
つまるところ、画像リソースを取得するリクエストに対するレスポンスに
`cross-origin-resource-policy：cross-origin`
のHTTPヘッダを追加してあげることにより、応答を受け取ったブラウザが
「あ、このリクエストは相手オリジン側も承知してくれているな」
と判断して無事に画像が表示できるということになる。

## BLOBストレージのみで対応可能か
調べた限りでは難しい。
Azure Storageには「CORS」という機能があるのでそこでオリジン間リソース共有のルールを設定すると
`Access-Control-Allow-Origin：[ここにWebサイトのオリジン]`
が追加されそうなのだが、今回はあくまでCORP対策の話なのでこの機能は該当しない。

2022年現在Azure Storage側にレスポンスのヘッダーをカスタムする機能は備わっていなさそう。
要するに、リクエストに対するレスポンスをBLOBストレージが返してから、クライアントに届くまでの間のどこかで
`cross-origin-resource-policy：cross-origin`
をヘッダ内に含める何かが必要になる。

## Azure CDNを利用する
Azure CDNで作成したエンドポイントの中に「ルール エンジン」という機能があるのでそれを利用する。

まずは「＋ エンドポイント」からエンドポイントを作成。ここで対象のBLOBストレージを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/760577db-50d6-69f9-74fe-57315b7cbdec.png)

エンドポイント作成後は配信元の設定などを実施（ここは説明省略）

エンドポイントURLで表示したいリソースが見えることを確認できたら本題の「ルール　エンジン」設定に入る。

### どのオリジンからでも許可する設定
1. 「グローバル」として最初から表示されているルールにある「アクションの追加」から「応答ヘッダーの変更」を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/d6af13c5-228f-1184-f9e9-84fe0d9ecaaa.png)

2. 項目の設定を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/161312a9-cd40-23cf-51cd-8d5f86c7dde6.png)

アクション：応答ヘッダー変更
|項目名|値|
|---|---|
|アクション|追加|
|HTTP ヘッダー名|cross-origin-resource-policy|
|HTTP ヘッダーの値|cross-origin|


保存すると反映に若干時間を要するが、反映後はどのオリジンからのリクエストに対してもレスポンス内に追加したHTTPヘッダーが存在する。

### オリジンの制限

無論、これだとセキュリティ的によろしくないのでアクセス元のオリジンを基に判断する様にしてあげたい。

1. 規則の追加を押して新しい規則を用意する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/530a6d2f-9163-9e9e-40e2-fb212f45db85.png)

2. 「条件の追加」から「要求ヘッダー」を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/203d5a48-e426-7d83-0acc-8f90d9d4039d.png)

3. 「アクションの追加」から「応答ヘッダーの変更」を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/41b78050-b975-7164-ecf9-ae653f6bffca.png)


4. 項目の設定を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/0eaa28c6-a770-d6b6-8ae5-77ceb45f87c9.png)

条件：要求ヘッダー
|項目名|値|
|---|---|
|ヘッダー名|Origin|
|演算子|次の値に等しい|
|ヘッダー値|[Webサイトオリジン]|
|大文字と小文字の変換|変換なし|

アクション：応答ヘッダー変更
|項目名|値|
|---|---|
|アクション|追加|
|HTTP ヘッダー名|cross-origin-resource-policy|
|HTTP ヘッダーの値|cross-origin|

## 確認方法
開発者ツールのネットワークで該当リクエストを開き、応答ヘッダー内に
`cross-origin-resource-policy：cross-origin`
が存在していればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/26283942-d54a-3c8c-6d8d-f955807c0d28.png)

## 参考URL

https://learn.microsoft.com/ja-jp/azure/cdn/cdn-cors
【React18】Suspenseの活用とReactのSSR進化

みなさんReact18での機能を活用してみたりはしましたでしょうか？

私もまだ業務ではこの素晴らしいアップデートの恩恵を受けているとは言えないのですが、自己学習の際に色々遊んでいる次第です。

そこで今回はReact18の新しい機能、<b>Suspense</b>に関して綴ってみます。

<h2>Suspenseに関してまとめると</h2>

今まで多くの反復作業を作り出したローディングロジック。

この作業を簡潔化するために、React18はLoading Stateデータの塊をコンポーネントの外部に移動して呼び出すようにしました。

<b>つまりは、コンポーネント内のデータを呼び出している間に、ユーザーが真っ白な画面を見ないようにする。そのため、そのコンポーネントを包むSuspenseがデータを全て呼び出す間レンダリングして、呼び出しが完了した際に完成されたコンポーネントを画面に出力する。</b>

簡単に説明すると、つまりはこういうことです。

では実際にコードを見ていきましょう。

<p>外部コンポーネントにてインポート</p>

![スクリーンショット 2022-12-23 14.59.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371709/381bc250-871a-3e33-e487-9ed4ce211380.png)


<p>今までのコード(こう見るとだいぶ簡潔化されている)</p>

![スクリーンショット 2022-12-23 14.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371709/bfbe02ad-0c34-edb3-a368-391963f0637e.png)

影響範囲もすぐに把握できて、データフローを素早く確認でき、非常に良いコードになってしまった。

<h2>SSR方式も画期的に便利で扱いやすくなった。</h2>

参考、<a href="https://im-developer.tistory.com/227">webローディング方式(SSR、CSR、SSG)</a>

ユーザーが空の画面が見えないようにSuspenseを適材適所に使用してみましょう。

![スクリーンショット 2022-12-23 15.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371709/3cf9a7cd-974a-8979-a78f-e35aee87d6fd.png)
※韓国語含んでてすみません。<작은데이터 />=小さいデータ。<큰데이터 />=大きデータ。という意味です。

ここで比較的呼び出しやすい小さいデータのコンポーネントは、すでに画面に見えている状態です。

Suspenseで包まれた<大きいデータ />コンポーネントが、サーバーサイドでローディングされている間、クライアント側のHTMLページは

```<Suspense fallback={<Loader />}> ```
の
```呼び出されたHTMLコード ex) <img src="loading.gif">```
を保持し、ローディングが完了した瞬間、そこに
```コンポーネントでローディングしたHTMLコード　ex) <ul class="big-list">...</ul>```
が代わりに画面に表示される。

このように各コンポーネントがレンダリングされるとき、hydrate（jsファイルまでブラウザにレンダリングされインタラクティブ状態）されていないReactコンポーネントをユーザーがクリックすると、ユーザーが望む動作をコンポーネントが優先的に機能させる。

非常に高速なレンダリングと使いやすさを保証してくれています。

次に期待されるのがServer Componentsの本格的な展開です。

バックエンドにあるReact.JSコードをブラウザがレンダリングするか(CSR)サーバがレンダリング(SSR)するかコンポーネントを選択的にレンダリングします。

つまり、<b>コンポーネントのレンダリングをサーバーで行う場合、レンダリング結果の値だけユーザーに送信し、重いjsデータをユーザーが直接ダウンロードしなくても利用できるようにすることで、ロード時間が短縮され、UXの満足度を上げることができるようになりました。</b>

また、基本方式がセキュリティに脆弱な方面レンダリング値のみを受け取るため、セキュリティに強く、使いやすさも直感的で簡単です。

<ul>
<li>file.server.js -> Server Component</li>
<li>file.client.js -> Client Component</li>
<li>file.js -> Universal Component</li>
</ul>

ぜひみなさん遊んでみてください。
Railsでdatetimeのミリ秒でハマった話

# はじめに
 仕事でコード書いていると、年に1回ぐらい日付関係の処理ではまるので、備忘録に記事を、まとめてました。


## 前提
DynamoDBを使用し、モデルは以下のように設定しています。

```ruby
class Notification
  include Dynamoid::Document
  include Draper::Decoratable

  table name: :notification, key: :notification_id
  range :notified_at, :datetime

  field :name, :string

  private

  def create_attrs(notification_id, name)
      base = { id: id, notified_at: Time.zone.now, name: name }
  end
end
```

まず、何にハマったかですが、notification_idとnotified_atでユニークな値を取得できる様にしたのですが、なぜか取得できない。。。

1つデータを作ったものとします。
```ruby
Notification.find('1', range_key: Notification.last.notified_at)

=> #<Notification:0x00000040hogehoge>が取得できる
```

実際にブラウザ側からパラメーターを送って取得する場合
DateTime型で送られてもparamsで一旦文字列に変換され、datetimeに戻す必要があるので、下記の様に取得してみる
```ruby
Notification.find('1', range_key: Notification.last.notified_at.to_s.to_datetime)
=> Dynamoid::Errors::RecordNotFound
```
なんで？！となった

## 結論
DiteTime型をStringに変換した際、ミリ秒部分がなくなり、再びDateTime型にしても、ミリ秒部分がなくなってしまうためであった。

## 説明
```ruby
Notification.last.notified_at
=> Mon, 12 Dec 2022 07:38:49 +0000

Notification.last.notified_at.to_s.to_datetime
=> Mon, 12 Dec 2022 07:38:49 +0000
```
上記の様に見ると同じ値である様に見える。
しかし
```ruby
Notification.last.notified_at == Notification.last.notified_at.to_s.to_datetime

=> false
```
これはDateTime型だと、ミリ秒までが表示されていないだけで、実際はミリ秒の値まであるため、falseとなっている。
この違いがTime型に変換してみるとよくわかった。
```ruby
Notification.last.notified_at.to_time
=> 2022-12-12 07:38:49.997983757 +0000

Notification.last.notified_at.to_s.to_datetime.to_time
=> 2022-12-12 07:38:49 +0000
```

ではどうすれば、
```ruby
Notification.last.notified_at

=> Mon, 12 Dec 2022 07:38:49 +0000

Notification.last.notified_at.iso8601(9).to_s.to_datetime
=> Mon, 12 Dec 2022 07:38:49 +0000

Notification.last.notified_at == Notification.last.notified_at.iso8601(9).to_s.to_datetime
=> true
```

```ruby
Notification.find('1', range_key: Notification.last.notified_at.iso8601(9).to_s.to_datetime)
=> #<Notification:0x00000040hogehoge>
```
取得できました。

## 終わりに

今回、ハマってしまったポイントとしては、DateTime型では表示されないだけで、ミリ秒の値も持っているということを認識してなかった点にあったと思います。
私だけかもしれませんが、つい表示されないとないものと思い込んでしまうことがあるので、備忘録として記事を残したいと思いました。
maya python visibility flags

```python
import pymel.core as pmc

def setShow():
    panelList = cmds.getPanel( type='modelPanel')
    modelPanelList = []
    modelEditorList = pmc.lsUI(editors=True)
    for myModelPanel in modelEditorList:
        if myModelPanel.find('modelPanel') != -1:
            modelPanelList.append(myModelPanel)
    for i in modelPanelList:
        cmds.modelEditor(i, 
            e=True,
            controllers=False,
            nurbsCurves=False,
            nurbsSurfaces=True,
            cv=False,
            hulls=False,
            polymeshes=True,
            subdivSurfaces=False,
            planes=False,
            lights=False,
            cameras=False,
            imagePlane=False,
            joints=False,
            ikHandles=False,
            deformers=False,
            dynamics=True,
            particleInstancers=False,
            fluids=False,
            hairSystems=False,
            follicles=False,
            nCloths=False,
            nParticles=False,
            nRigids=False,
            dynamicConstraints=False,
            locators=False,
            dimensions=False,
            pivots=False,
            handles=False,
            textures=False,
            strokes=False,
            motionTrails=False,
            pluginShapes=True,
            clipGhosts=False,
            greasePencils=False,
            pluginObjects=[
                'gpuCacheDisplayFilter',False
            ],
            manipulators=True,
            grid=False,
            hud=False,
            hos=True,
            sel=True
        )

setShow()
```
非線形最適制御入門　大塚敏之先生　コロナ社

```r

#p.136 
#パラメータがuのみの場合

#4次のルンゲクッタ
#dx/dt=x*(1-x)、 x(0)=0.01、f(x,u,t)=x*(1-x)　を解く

f=function(tt,xx){
return(xx*(1-xx))  
}

t=0
t0=t
x=0.01

x_vec=c()
t_vec=c()

tf=1
ite=100
h=tf/ite

for(l in 1:ite){
x_vec=c(x_vec,x)
t_vec=c(t_vec,t)  
s1=f(t,x)
s2=f(t+h/2,x+h*s1/2)
s3=f(t+h/2,x+h*s2/2)
s4=f(t+h,x+h*s3)
x=x+h*(s1+2*s2+2*s3+s4)/6
t=t+h
}

#評価関数
L=function(tt,xx,uu){
return(-log(xx)*uu^2-log(xx)*(uu-1)^2)  
}

#終端時点のコスト
pthi=function(xx){
return(xx*(1-xx))  
}

cost=function(uu){
#L(t,x,u)の数値積分の計算
integral=0
for(i in 1:ite){
integral=integral+L(t_vec[i],x_vec[i],uu[i])*h
}  
return(pthi(x_vec[length(x_vec)])+integral)
}

#勾配降下法
u=rep(1,ite)
Ite=10^4
eta=0.9
dh=0.001

for(l in 1:Ite){
for(i in 1:length(u)){  
usub=u;usub[i]=usub[i]+dh
u[i]=u[i]-eta*(cost(usub)-cost(u))/dh  
}
print(cost(u))      
}



```
adminLTEの画面リロード時に出現するロゴを変更したい・そもそもローディング画面消したい

# 追記

なし

# はじめに

adminLTEっていう管理画面を簡単に作成できますよってツール知ってますか。
使ったことない人はぜひ調べて、触ってみてください。感動します。

そのadminLTEなんですが画面リロードするたびに専用のロゴとともにローディング画面が表示されます。
私は特にそのままでも大丈夫な人なんですが、中には「ロゴ替えたい」とか「ローディング画面いらなくね」なんて人もいるかと思いますので、解決法調べました。

では、どうぞ。

# ロゴ変更する場合の記述

### 画像アップロード
```Bash
public/vendor/adminlte/dist/img
```
上記ディレクトリ配下に変更したいロゴの画像をアップロードしましょう。
（※既にデフォルトのAdminLTELogo.pngが存在しているはずです）

私は今回はsampleLogo.pngというファイルをアップロードすることとします。
こんな感じですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3076818/04f2be6e-423c-1f4a-110e-45b2e5bc1b40.png)

### パスの変更(config/adminlte.php)
```php:adminlte.php
    'preloader' => [
        'enabled' => true,
        'img' => [
            'path' => 'vendor/adminlte/dist/img/sampleLogo.png',
            'alt' => 'AdminLTE Preloader Image',
            'effect' => 'animation__shake',
            'width' => 60,
            'height' => 60,
        ],
    ],
```

これだけでロゴが変更されているはずです。
ぜひ確認してみてください。
もちろんwidth,heightを変更すればロゴの大きさが変わりますので好みのカスタム探していろいろお試しください。

# ローディング画面を表示しない場合の記述

### 有効フラグの変更(config/adminlte.php)
```php:adminlte.php
    'preloader' => [
        'enabled' => false,
        'img' => [
            'path' => 'vendor/adminlte/dist/img/adminLTELogo.png',
            'alt' => 'AdminLTE Preloader Image',
            'effect' => 'animation__shake',
            'width' => 60,
            'height' => 60,
        ],
    ],
```

上記のenableをfalseに設定してやることによってローディング画面を表示させないこともできる。
表示したくなって戻すときはtrueを設定すればよいです。

こんな簡単にローディング画面の表示・非表示も設定できちゃいます。
adminLTEすごいですねぇ。

# まとめ

記事調べてもなんかいい感じのが出てこなかったので、adminLTELogoでgrepかけていろんなファイル変更しまくりでした。
たいへんでした。

# 参考リンク

なし
AWS CPU 使用率アラームの作成

# アラーム作成
EC2->インスタンス選択->モニタリング->メトリクスで表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/4fbe59be-5d38-8ae7-fec0-6baa7a3e3597.png)

グラフ化したメトリクス->アクション->アラーム作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/b1239525-8ddb-5deb-601b-ed75ca94e797.png)

すきにtuneして
EC2 アクションつかうなら静的を設置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/514e12b4-4e7c-732f-89b1-2c4b026375ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/7185115a-57b4-7364-4197-8e98744d094c.png)

新しいトピックの作成->トピックの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/82ca262a-8959-b64d-3c3d-53a8ff5524dc.png)


再起動のアクションもある
EC2 アクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/b4f5f532-a41a-f258-5d38-4b4302f3f690.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/81341614-9708-0680-8f1a-f9bc39bb8c53.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/f88c42c2-766a-90a6-5da2-02772685e617.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/c50f92c6-e094-c585-5a34-3015692e99ac.png)
アラームの作成

emailならmailboxかくにん

# ダッシュボード追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/de012944-eccf-e8bb-ec19-8311a756b3d9.png)

新規作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/e2487505-40c5-2bed-133b-5cebf4dd398a.png)
ダッシュボード追加
フレームワークとライブラリの違い

# 概要

* フレームワークの説明
* ライブラリの説明
* フレームワークとライブラリとの違い

# フレームワークの説明
「フレームワーク」という言葉は「骨組み」という意味があります。
アプリケーション開発において、テンプレートの役割を持っており、開発を行う際に必要とされる「基礎的な機能」をまとめて提供してくれるものです。
**「アプリケーション開発で必要となる作業やリソースを事前に仮定し、必要なものがデフォルトで用意してある便利なもの」** というイメージです。

# ライブラリの説明
「ライブラリ」という言葉は「図書館」という意味があり、プログラミングにおける拡張機能をライブラリと呼びます。

他のプログラムと組み合わせて使用するために、複雑なプログラムを1つのセットにしたものです。複雑な機能実装でも、ライブラリをアプリへ読み込ませることにより簡単に実装できるようになります。
 **「便利な機能を集めておいて、簡単に使える仕組み」** というイメージです。

# ライブラリとの違い
どちらも開発を効率化するために作られたものですが少し違います。

**フレームワーク**
→アプリケーションを開発するために必要な機能がデフォルトで揃っているもの。アプリケーションで動く骨組みが用意されているので、追加でプログラムを書かなくても最低限のアプリケーションとして動く。

**ライブラリ**
→ライブラリは開発の作業をできるだけ簡略化するために使用できる予め書き込まれたプログラムの集まり。プログラムや特定の処理で必要なときに呼び出して使う。

# 最後に
今回学んだ事をアウトプットとして文字に書き起こす事で、学習した内容がやっと自分の中に落とし込まれた感覚を覚えました。
拙く、まだまだ知識は浅いですが、また懲りずに書いていけたらと思います。

間違っている点がございましたらご指摘いただけたら幸いです。
最後までお付き合いいただき誠にありがとうございました。
SvelteKitのSSRをAWS上にデプロイ

## はじめに

SvelteKitで作成したSSR(サーバーサイドレンダリング)のアプリケーションをVercelではなく、AWS上にデプロイしたく、試行錯誤した時の記録をここにメモとして投稿します。

## 1. SSRの仕組みを調べた。

SSR(サーバーサイドレンダリング)とは、サーバー再度でレンダリング(HTMLを生成)し、レスポンスを返すこと。

AWSでやる場合はlambdaに処理を持たせて、API Gateway経由でHTMLを表示させる。

## 2. SvelteKitのデプロイ方法を探る

nextjsやnuxtjsと同じようにbuildの形をいい感じに変えることができ、  
標準では`@sveltejs/adapter-auto`というアダプターによりデプロイ用のアウトプットファイルを生成している。

標準の@sveltejs/adapter-autoでは、

* Cloudflare Pages
* Netlify
* Vercel

にはデプロイ可能。

AWSにデプロイするためにはどうしたらいいんだ～～

## 3. 一回諦めてSPAに妥協した

SPA用のアダプターとして、'@sveltejs/adapter-static'というものがあったので、そちらで試してみる。

### yarnインストール

```
yarn add '@sveltejs/adapter-static'
```


### アダプターを設定
   
```typescript:svelte.config.js
import { adapter } from '@sveltejs/adapter-static'
```

### build実行

```bash
yarn build
```

<font color="red">何かよく分からないエラー再び...</font>

prerenderがなんとかかんとか...

## 4. prerenderを+layout.tsでtrueにすればよいらしい

<font color="red">[id].svelteではprerenderできないというエラー</font>

prerenderをtrueにすると、事前にレンダリングをしておくことができるというもの。

確かに[id]のようなページでは事前にレンダリングしておくことはできないですね...
(やる方法もありそうでしたが、よくわかりませんでした..)

### SPAでデプロイするのは諦めて、SSRに戻ります。

## AWS用のアダプターを発見！

[https://github.com/MikeBild/sveltekit-adapter-aws](https://github.com/MikeBild/sveltekit-adapter-aws)
こちらを使ってみる。


1. yarn add sveltekit-adapter-aws
2. svelte.config.js編集

```
// svelte.config.js
import { adapter } from 'sveltekit-adapter-aws'
・・・省略
    adapter: adapter({
      autoDeploy: true,
    }),
・・・省略
```

ビルドの後に自動でデプロイされるようにしました。

結果。。。

### <font color="red">CloudFrontでnameエラー。</font>

400エラーで何かの名前に使えない文字があるらしい。。。

### <font color="red">なぜ...</font>


この後しばらく放置しました...w


## 原因 ⇒ 修正 ⇒ 成功！

失敗しているCloudFormationのテンプレートを確認すると、CloudFrontの箇所に違和感が...

```
・・・省略
      '??.png'
・・・省略
```

## ん？なんだこれは

ソースコードを確認すると、

```
|- static
  |- ロゴ.png
```

<font color="red">これかもしれない...！</font>

ということで`ロゴ.png`を`logo.png`に変更したところ無事デプロイ完了！ヤッター！
windows chrome ウィンドウサイズがおかしい

原因判明

NVIDIA Desktop Manager がダメだった。
これを無効にしたら治った。


strokeit は、 startup フォルダに登録するのではなく、タスクスケジューラーで自動起動すること。管理者権限はオフで。（オンにすると挙動がおかしくなる。）

# 以下メモ。。。



なぜかchromeのサイズがおかしい。
ctrl + n で新しいウィンドウを開くと小さいサイズでしか開かない。

# 解決方法

・chromeを管理者権限で常に開く
・strokeit(マウスジェスチャー)を管理者権限で開く (タスクスケジューラー登録)
でできた。管理者権限でマウスジェスチャを開いて置かないとchrome上で動かない

これで一応できるけど、uwscが聞かないので

ショートカットアイコンを右クリックプロパティ

```
C:\Users\[your]\AppData\Local\Google\Chrome\Application\chrome.exe --window-size=1200,1920 --window-position=-1200,0
```

で解決？



# トライしたがダメだった方法

・preferences の設定を変更する

```
中身が空で設定されていないので、変更する余地もない。
```





# windowresizer

```
まるでダメ
```


# ショートカットプログラムにサイズを指定

```
"C:\Program Files\Google\Chrome\Application\chrome.exe" --window-position=150,10 --window-size=1190,880
```

ctrn + n で開くわけなので、解決にならない。
Mac はてなブログ記事 一括でダウンロード

```
①はてなブログの管理画面→
②設定→
③詳細設定→
④エクスポートの記事のバックアップと製本サービス→
⑤ダウンロード
```
で取得した`XXXXXX.export.txtファイル`をデスクトップに置いて、
`空のimgフォルダ`を作成します。`XXXXXX`は正式な名称に変えて下さい。

ターミナルを立ち上げて、デスクトップに移動します。
```
cd Desktop/
```
`grepコマンド`の`-oオプション`で検索にマッチした部分のみを`photo.txtファイル`に出力します。
```
grep "https\:\/\/cdn-.*png\|https\:\/\/cdn-.*jpg" -o XXXXXX.export.txt > photo.txt
```
この時に`zsh: no matches found:`で怒られたら、別シェル画面を立ち上げて`ホーム`の位置で
```
open ~/.zshrc
```
で`.zshrc`を開いて
![スクリーンショット 2022-12-23 14.32.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/a44a6cf6-e58d-7e3e-ee89-64d41ca918f4.png)
```
setopt +o nomatch
```
を加えて`command` + `s`で保存して
```
source ~/.zshrc
```
して設定を反映させて下さい。それでも怒られるようでしたら`zsh`をインストールしてない可能性があります。
```
brew install zsh
```
無事に`photo.txtファイル`に出力できた場合は、下記コマンドで`imgフォルダ`に移します。
```
cd img/
```
```
xargs -n 1 curl -O < ../photo.txt
```
マイグレードされ、`imgフォルダ`に画像が流れ込みます。