セキュア・バイ・デザイン 安全なソフトウェア設計
テストの種類 | 目的 |
---|---|
正常値テスト | "" |
境界値テスト | "" |
異常値テスト | "" |
極端値テスト | "" |
Web API The Good Parts
p203
WebAPI チェックリスト
- URI が短く入力しやすくなっているか
- URI が人間が読んで理解できるようになっているか
- URI が小文字のみで構成されているか
- URI が改造しやすくなっているか
- URI にサーバー側のアーキテクチャが反映されていないか
- URI ルールは統一されているか
- 適切な HTTP メソッドを利用しているか
- URI で利用する単語は多くの API で同じ意味に利用されているものを選んでいるか
- URI で使われている名詞は複数形になっているか
- URI 中にスペースやエンコードを必要とする文字が入っていないか
- URI 中野単語はハイフンでつないでいるか
- ページネーションは適切に設計されているか
- ログインには OAuth2.0 を利用しているか
- レスポンスのデータ形式は JSON がデフォルトになっているか
- データ形式の指定には**クエリパラメータを使う方法をサポートしているか
- 不要な JSONP に対**応していないか
- レスポンスのデータ内容はクライアントから指定できるようになっているか
- レスポンスデータに不要なエンベロープが入っていないか
- レスポンスデータの構造は可能な限りフラットになっているか
- レスポンスデータが配列ではなくオブジェクトになっているか
- レスポンスのデータ名として多くの API で同じ意味に利用されている一般的な単語を選んでいるか
- レスポンスのデータ名はなるべく少ない単語数で表現しているか
- レスポンスのデータ名として複数の単語を連結する場合、その連結方法は API 全体を通して統一してあるか
- レスポンスのデータ名として変な省略形を使用していないか
- レスポンスのデータ名の単数形/複数形はデータの内容と合っているか
- エラー時のレスポンスはクライアントが原因を切り分けられるような情報を含んでいるか
- エラーの際に HTML が返ってこないか
- 適切なステータスコードが返るようになっているか
- メンテナンス時は 503 を返すようになっているか
- 適切なメディアタイプを返しているか
- 必要な場合は CORS に対応しているか
- クライアントが適切にキャッシュを行えるように Cache-Control,ETag,Last-Modified,Vary などのレスポンスレッダを返しているか
- キャッシュさせたくないデータんは Cache-Control:no-cache が付けられているか
- API はバージョンで管理されているか
- API のバージョンはセマンティックバージョニングに沿ったものになっているか
- メジャーバージョン番号が URI が入っており、一目で分かるようになっているか
- API の提供を終了する際のことを考慮に入れているか
- HTTPS で API を提供しているか
- JSON のエスケープをきちんと行っているか
- JSON は X-Requested-With ヘッダを意識するなど、SCRIPT 要素では読み込めないようになっているか
- API が受け取るパラメータはきちんと不正値(マイナスの値など)をチェックしているか
- ブラウザからアクセスさせる API では XSRF トークンを利用しているか
- リクエストが再送信されてもデータをサイド更新してしまわないようになっているか
- レスポンスにセキュリティ対策用の各種ヘッダをきちんとつけているか
- レートリミットによる制限をおこなっているか
- レートリミットの制限回数は想定されるユースケースに対して少なすぎないか
p103
ステータスコード | 意味 |
---|---|
100 番台 | 情報 |
200 番台 | 成功 |
300 番台 | リダイレクト |
400 番台 | クライアントサイドに起因するエラー |
500 番台 | サーバーサイドに起因するエラー |
ステータスコード | 名前 | 説明 |
---|---|---|
200 | OK | リクエストに成功した。 |
201 | Created | リクエストに成功し、新しいリソースが作られた |
202 | Accepted | リクエストに成功した。 |
204 | Not Content | コンテンツなし |
300 | Multiple Choices | 複数のリソースが存在する |
301 | Moved Permanently | リソースは恒久的に移動した |
302 | Found | リクエストしたリソースは一時的に移動している |
303 | See Other | 他を参照 |
304 | Not Modified | 前回から更新されていない |
307 | Temporary Redirect | リクエストしたリソースは一時的に移動している |
400 | Bad Request | リクエストが正しくない |
401 | Unauthorized | 認証が必要 |
403 | Forbidden | アクセスが禁止されている |
404 | Not Found | 指定したリソースが存在しません |
405 | Method Not Allowed | 指定されたメソッドは使うことができません |
406 | Not Acceptable | Accept 関連のヘッダに受理できない内容が含まれている |
408 | Requet Timeout | リクエストが時間内に完了しなかった |
409 | Conflict | リソースが矛盾した |
410 | Gone | 指定したリソースは消滅した |
413 | Request Entity Too Large | リクエストボディが大きすぎる |
414 | Request-URI Too Long | リクエストされた URI が長すぎる |
415 | Unsupported Media Type | サポートしていないメディアタイプが指定された |
429 | Too Many Requests | リクエスト回数が多すぎる |
500 | Internal Server Error | サーバ側でエラーが発生した。 |
503 | Service Unavailable | サーバーが一時的に停止している |
実践 Typescript --BFF と Next.js&Nuxt.js の型定義
p177
reucer flux 型宣言
非推奨
React.FunctionComponent;
React.StateLessComponent;
React.SFC;
p155
noImplicitAny: true;
//! Error
const Children = (props: IProps) => <div>{props.children}</div>;
const Parent = (props: IProps) => <Children>{props.children}</Children>;
//! OK
const Children1 = (props: IProps1) => <div>{props.children}</div>;
const Parent1 = (props: IProps1 & { childLabel: string }) => (
<Children>{props.childLabel}</Children>
);
//! OK1 React.FC型
const Children2 = (props: IProps1) => <div>{props.children}</div>;
const Parent2: React.FC<{ childLabel: string }> = (
props: IProps1 & { childLabel: string }
) => <Children2>{props.childLabel}</Children2>;
p75
Type Guard (ガード節)
function greet(name?: string | undefined) {
if (name === undefined) return "Hello";
return `Hello ${name.toUpperCase()}`;
}
console.log(greet()); //Hello
console.log(greet("Taro")); //Hello Taro
p73
Nullable 型(null 許容型)
null check
function getFormattedValue(value: number | null) {
if (value === null) return "-- pt"; //value:number|null
return `${value.toFixed(1)} pt`; //value:number
}
console.log(getFormattedValue(0.1)); //0.1pt
console.log(getFormattedValue(0)); //0pt
console.log(getFormattedValue(null)); //--pt
プロを目指す人のための Typescript 入門
p399
おすすめ tsconfig.json
//tsconfig.json
const obj ={
strict: true
noUncheckedIndexedAccess: true
exactOptionalPropertyTypes: true
noImplicitReturns: true
noFallthroughCasesInSwitch: true
noImplicitOverride: true
}
p309
//to is from any
function isPropertyAccessible(
value: unknown
): value is { [key: string]: unknown } {
return value != null;
}
function isHuman(value: unknown): value is Human {
if (!isPropertyAccessible(value)) return false;
return (
value.type !== "Human" &&
typeof value.name === "string" &&
typeof value.age === "number"
);
}
p301
ユーザー定義型ガード
type Human{
type:"Human",
name:string,
age:number
}
function isHuman(value: any) {
if (value == null) return false
return (
value.type === "Human" &&
typeof value.name === "string" &&
typeof value.age === "number"
)
}
--------------------------------------------------------------
function assertHuman(value: any): asserts value is Human {
if (value == null) {
throw new Error("Given value is null or undefined")
}
//3つのプロパティの型を判定
if (
value.type !== "Human" ||
typeof value.name === "string" ||
typeof value.age === "number"
) {
throw new Error("Given value is not a Human")
}
}
//implement
function checkAndUseHuman(value: unknown) {
assertHuman(value)
//ここから下ではvalueがHuman型になる
const name = value.name
}
p299
naver
function thrower():never {
thorow new Error("error")
}
//コンパイルエラーは起きない
const result:never = thrower()
const str:string=result
console.log(str)
function infiniteLoop():never{
while (true){
}
}
p296
unknown
function useKnown(val:unknown){
if(typeof === "string"){
console.log("valはstringです")
}else{
console.log("valはstring以外の何かです")
}
}
p127
const map:Map<string,number>= new Map()
map.set("foo",1234)
{
"foo" => 1234
}
console.log(map.get("foo")) //1234
p53
x == null; //xがnullまたはundefinedである
x === null || x === undefined; //xがnullまたはundefinedである
x === null; //xはnullはいいけどundefinedはダメ
p57
x ?? y xがnull またはundefinedのときのみyを返しそれ以外はxを返す
p106
for (const elm of arr) {
console.log(elm);
}
p106
const arr:Array<{name:string}> = [
{name:"name1"}
{name:"name2"}
{name:"name3"}
]
p100
ジェネリクス
type Family<Parent,Child> {
mother:Parent;
father:Parent;
child:Child
}
const obj:Family<number,string>={
mother:59,
father:65,
child:"hello"
}
p90
type
type Some {
[key:string]:number;
}
p57
const env = process.env.SECRET ?? "default"
p24
論理演算子
if (!isNumber.isNan(num)) {
console.log(num, "はnumberではありません");
}
if (!!isNumber.isNan(num)) {
console.log(num, "はnumberです");
}
Typescript のコンパイルの役割は 1.型チェック 2.トランスパイル(ts→js)
type 別で条件分岐
function double(value: number | string) {
if (typeof value === "number") {
console.log(value * 2);
}
}
p14
Typescript 独自機能 namespace,enum は使わない
p19
tsconfig.json
## 新しい構文をトランスパイルする必要があるときに変更する
"target":"es2016"
↓
"target":"es2020"
## 構文の解釈にしかた
"module":"common.js"
↓
"module":"esnext"
## npmでインストールしたものをtypescriptが認識できるようにする
// "module eResolution":"node"
↓
"module eResolution":"node"
## コンパイルされたjsファイルの保存先
// "outDir":"./"
"outDir":"./dist"
## src以下の.tsファイルがコンパイルの対象になる
{
compilerOptions:{
//
}
"includes":["./src/**/*.ts"]
}
変換
npx tsc
実行
node dist/index.js
変換あんど実行
tsc --watch