REST におけるベストプラクティス

REST API の記事は, 今となっては普通にありふれています.

ほとんどのWEBアプリケーションの一部として利用されています.

シンプルで, 一貫性のある, 実用的なインターフェイスが必須で, そうであれば, 他の人が使う場合にかなり簡単にAPIを使うことができます.

これらのプラクティスが当たり前に思うかも知れませんが, よくこれを順守していない人をよく見かけますのでこの投稿を書くことにしました.

figure001

これらは RESTful API を設計するときに心に止めておくプラクティスです.

お断り:
これらのプラクティスは私の過去の経験から生まれたものです.
もし, あなたがそうは思わなければ,気軽にメールを送ってください.
そしてそれについて議論しましょう.

 

APIのバージョン

APIのバージョンは必須にすべきです. これは, 将来, APIの時系列変化の記録となります.

ひとつの方法としてはURLのパス部分にそれを含める方法があります.

/api/v1/...

もうひとつの方法としては, HTTPヘッダ Accept を利用する方法です.
GitHub でも使われています.

バージョンを使うことで, 古いクライアントとの互換性を気にすることなくAPI構造を変更できるようになります.

 

「動詞」でなく「名詞」を使う

「名詞」でなく「動詞」をリソース名に使っているのをよく見かけます.

悪い例 :

/getProducts
/listOrders
/retreiveClientByOrder?orderId=1

簡潔でわかりやすい構造として「名詞」を使うべきです.
HTTPメソッドを上手に使えばリソース名からアクション部分をなくすことができます.

良い例 :

GET /products : product の全リストを返す
POST /products : product を追加する
GET /products/4 : product #4 を取得する
PATCH/PUT /products/4 : product #4 を更新する

 

「複数形」を利用する

単数形と複数形のリソース名を混合するのはよくないです.
すぐに混乱して一貫性がなくなります.

アクションが show/delete/update だとしても
/artist は使わず /artists を使う.

 

GET / HEAD の利用は常にセーフティに使う

RFC2616 では, HEAD / GET メソッドは, 常にセーフティであるべきだと示されています. (ステータスの変更はすべきでない)

悪い例 :

GET /deleteProduct?id=1

検索エンジンのページインデックスを想像してみてください.

 

リソースのネストを利用する

コレクション内のコレクションを取得したいとき, 簡潔な設計として、ネストされたルーティングを使用します。

特定のアーティストのすべてのアルバムのリストを取得したい場合 :

GET /artists/8/albums

 

ページング

HTTP上で非常に大きな結果セットを返すことはいい考えではありません。
巨大なJSONをシリアライズすることは高コストとなり, 最終的にパフォーマンスの問題となります.

それを回避するために「ページ分割」が1つの選択肢となります.
Facebook, Twitter, Github などもそうしており,
短時間の複数回の呼び出しは, 一回の巨大な大変遅い実行より大変効果的です.

また, ページネーションを使用している場合にも、リンクのHTTPヘッダーに、
次と前のページのリンクを示しておくことは1つの良い方法です。GitHubもそうしています.

 

適切な HTTPステータスコード を利用する

コンテンツを返す際には、Success/Error のリクエスト両方に対して必ず適切なHTTPステータスコードを使用して返します.

以下, アプリケーションで利用できるコードの簡単なリストです.

Success codes

201 Created should be used when creating content (INSERT),
202 Accepted should be used when a request is queued for background processing (async tasks),
204 No Content should be used when the request was properly executed but no content was returned (a good example would be when you delete something).

Client error codes

400 Bad Request should be used when there was an error while processing the request payload (malformed JSON, for instance).
401 Unauthorized should be used when a request is not authenticiated (wrong access token, or username or password).
403 Forbidden should be used when the request is successfully authenticiated (see 401), but the action was forbidden.
406 Not Acceptable should be used when the requested format is not available (for instance, when requesting an XML resource from a JSON only server).
410 Gone Should be returned when the requested resource is permenantely deleted and will never be available again.
422 Unprocesable entity Could be used when there was a validation error while creating an object.

なお, RFC2616 でステータスコードの全リストを見ることができます.

 

常に一貫してエラーペイロードを返す

例外が発生したとき、一貫して常にエラーを説明するペイロードを返します。
こうすることで, どのエラーメッセージも(構造は常にエラーが何であれ同じ)パースが容易になります。

以下は, 私がよくWebアプリケーションで使用するものです。
それは、明確でシンプルに内容を説明しています。

HTTP/1.1 401 Unauthorized
{
"status": "Unauthorized",
"message": "No access token provided.",
"request_id": "594600f4-7eec-47ca-8012-02e7b89859ce"
}

 

追記

などとえらそうに書きましたが全ては以下の意訳です.

Some REST best practices
https://bourgeois.me/rest/

改めて, 心に深く刻むことができたように思います.


Related Categories :  DevelopmemtRecommendedWEB


Yosemite で Android-Studio 起動時に噂の「Java6 が古い」

おっと! でました!

yosemite

どこかで読んだよ! そんな話!

ダイアログのボタンから遷移しますダウンロードページ.

Java_for_OS_X_2014-001

Java for OS X 2014-001

そのまま言われるがままに流れて, AndroidStudio 起動OK, と.


docker 1.3 で MacOSX でもフツーに共有できようになった

$ docker run -v /Users/bob/myapp/src:/src [...]

これまでは, 使えなかったけどOSXでファイル共有.

Docker コンテナと Mac OSX で ファイルを共有する

Docker_1_3__signed_images__process_injection__security_options__Mac_shared_directories___Docker_Blog

バージョン1.3 で可能になってますよ.

Docker 1.3: signed images, process injection, security options, Mac shared directories | Docker Blog

手間のかかるサイズ制限で面倒だった,

各ビルド環境をMacOSXでも簡単に揃えることがほとんどすべて可能になった.

Docker の更新内容て, ユーザの要望の中で確実にまともなものを捉えてるよね.


マテリアル・デザインのアイコンセットを使いやすい配置に変える

たくさんの画像リソースが公開されています.

Material_Icons_Index

【使える! 即保存】 github で公開されている Material design icons 一覧

どれもいいかんじです.

で, これ一覧で好きなアイコンを選んだあと,

zipをダウンロード/展開したあとどれを使ったらいいのか.

たとえば, 一覧で「error」アイコンを使おうとすると

こんなにある.

./alert/drawable-hdpi/ic_error_black_18dp.png
./alert/drawable-hdpi/ic_error_black_24dp.png
./alert/drawable-hdpi/ic_error_black_36dp.png
./alert/drawable-hdpi/ic_error_black_48dp.png
./alert/drawable-hdpi/ic_error_grey600_18dp.png
...(略)...
./alert/drawable-xxxhdpi/ic_error_red_48dp.png
./alert/drawable-xxxhdpi/ic_error_white_18dp.png
./alert/drawable-xxxhdpi/ic_error_white_24dp.png
./alert/drawable-xxxhdpi/ic_error_white_36dp.png
./alert/drawable-xxxhdpi/ic_error_white_48dp.png

ディレクトリの構造はこんなかんじになってる.

material-design-icons-master
├── action
│   ├── drawable-hdpi
│   │   ├── ic_error_red_18dp.png
│   │   ├── ic_error_red_24dp.png
│   │   ├── ic_error_red_36dp.png
│   │   ├── ic_error_red_48dp.png
│   ├── drawable-mdpi
│   ├── drawable-xhdpi
│   ├── drawable-xxhdpi
│   ├── drawable-xxxhdpi

アイコンファイルを選択する他に

いくつか決めなければならないことがあったりします.

・dpi
・color
・dip

「色」は見て決めれるけども...

以下を見ながら, dip(サイズ/スケール) と

対象ファイル, 新しいファイル名を決める.

Launcher ic_launcher_***.png 48dp
Action Bar ic_menu_***.png 32dp
Small/Contextual ic_***.png 16dp
Notification ic_stat_notify_***.png 24dp

Iconography | Android Developers

細かくいろいろ区別できるのだろうけど,

Android Studioのプロジェクトデフォルトdpiの構成に

drawableディレクトリはとりあえず合わせよう.

res
├── drawable-hdpi
│   └── ic_error.png
├── drawable-mdpi
│   └── ic_error.png
├── drawable-xhdpi
│   └── ic_error.png
├── drawable-xxhdpi
│   └── ic_error.png

などとシコシコ手動でやってみたがめんどうなので

zip の展開後のディレクトリ構成とファイル名を

あらかじめ変更しておけば, フォルダごと上書きできそうなので

一括でスクリプトで以下に変更しておく.

{category}/drawable-{dpi}/ic_{name}_{color}_{dip}.png

{category}/{name}/{color}/{dip}/drawable-{dpi}/ic_{name}.png

<?php
/**
 Restructure dirs/files tree.
 
https://github.com/google/material-design-icons
 
Usage:
 
$ curl -LO https://github.com/google/material-design-icons/archive/master.zip
$ unzip material-design-icons-master.zip
$ ls
... material-design-icons-master ... 
$ php restructure.php
 
{category}/drawable-{dpi}/ic_{name}_{color}_{dip}.png
-> {category}/{name}/{color}/{dip}/drawable-{dpi}/ic_{name}.png
 
 
~/material-design-icons-master_new $ tree . 
.
├── action
│   ├── 3d_rotation
│   │   ├── black
│   │   │   ├── 18dp
│   │   │   │   ├── drawable-hdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-mdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-xhdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-xxhdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   └── drawable-xxxhdpi
│   │   │   │       └── ic_3d_rotation.png
│   │   │   ├── 24dp
│   │   │   │   ├── drawable-hdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-mdpi
│   │   │   │   │   └── ic_3d_rotation.png
...
*/
 
foreach (glob('material-design-icons-master/*/*/*.png') as $file) {
  if (is_file($file) && preg_match('@/drawable@', $file)) {
    $path_parts = pathinfo($file);
    $filename = $path_parts['filename'];
    $dirs = explode('/', $path_parts['dirname']);
    $category   = $dirs[1];
    $dip        = substr($filename, strrpos($filename, '_') + 1);
    $dpi        = substr($dirs[2], strpos($dirs[2], '-') + 1);
    $filename   = substr($filename, 0, strpos($filename, '_' . $dip));
    $name_color = substr($filename, strpos($filename, '_') + 1);
    $color      = substr($name_color, strrpos($name_color, '_') + 1);
    $name       = substr($name_color, 0, strpos($name_color, '_' . $color));
    $path = sprintf('%s_new/%s/%s/%s/%s/drawable-%s/ic_%s.png',
                    $dirs[0], $category, $name, $color, $dip, $dpi, $name);
    mkdir(dirname($path), 0777, true);
    copy($file, $path);
    echo $file . "\n";
    echo '-> ' . $path . "\n";
  }
}

ディレクトリ構成を変更 - gist

構成変更後はこんなかんじに.

~/material-design-icons-master_new $ tree . 
.
├── action
│   ├── 3d_rotation
│   │   ├── black
│   │   │   ├── 18dp
│   │   │   │   ├── drawable-hdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-mdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-xhdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-xxhdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   └── drawable-xxxhdpi
│   │   │   │       └── ic_3d_rotation.png
│   │   │   ├── 24dp
│   │   │   │   ├── drawable-hdpi
│   │   │   │   │   └── ic_3d_rotation.png
│   │   │   │   ├── drawable-mdpi
│   │   │   │   │   └── ic_3d_rotation.png
...

こうしておけば,

使いたいアイコンの色, 利用場所(dip) を考えながら,

GUI上でディレクトリごと上書きで,

IDE上の res ディレクトリ以下にコピーすればよい.

icon_copy

よくみると, IDE側の drawable-*** のディレクトリ名は微妙に違ってたりするが(笑)


【使える! 即保存】 github で公開されている Material design icons 一覧

今, 話題の「Material Design」.

アイコンリソースが公開されています.

google/material-design-icons

いちいち zip ダウンロードして眺めるのもなんなので,

一覧にしておく.

action


3d rotation

accessibility

account balance

account balance wallet

account box

account child

account circle

add shopping cart

alarm

alarm add

alarm off

alarm on

android

announcement

aspect ratio

assessment

assignment

assignment ind

assignment late

assignment return

assignment returned

assignment turned in

autorenew

backup

book

bookmark

bookmark outline

bug report

cached

class

credit card

dashboard

delete

description

dns

done

done all

event

exit to app

explore

extension

face unlock

favorite

favorite outline

find in page

find replace

flip to back

flip to front

get app

grade

group work

help

highlight remove

history

home

https

info

info outline

input

invert colors

label

label outline

language

launch

list

lock

lock open

lock outline

loyalty

markunread mailbox

note add

open in browser

open in new

open with

pageview

payment

perm camera mic

perm contact cal

perm data setting

perm device info

perm identity

perm media

perm phone msg

perm scan wifi

picture in picture

polymer

print

query builder

question answer

receipt

redeem

reorder

report problem

restore

room

schedule

search

settings

settings applications

settings backup restore

settings bluetooth

settings cell

settings display

settings ethernet

settings input antenna

settings input component

settings input composite

settings input hdmi

settings input svideo

settings overscan

settings phone

settings power

settings remote

settings voice

shop

shop two

shopping basket

shopping cart

speaker notes

spellcheck

star rate

stars

store

subject

supervisor account

swap horiz

swap vert

swap vert circle

system update tv

tab

tab unselected

theaters

thumb down

thumb up

thumbs up down

toc

today

track changes

translate

trending down

trending neutral

trending up

turned in

turned in not

verified user

view agenda

view array

view carousel

view column

view day

view headline

view list

view module

view quilt

view stream

view week

visibility

visibility off

wallet giftcard

wallet membership

wallet travel

work

alert


error

warning

av


album

av timer

closed caption

equalizer

explicit

fast forward

fast rewind

games

hearing

high quality

loop

mic

mic none

mic off

movie

my library add

my library books

my library music

new releases

not interested

pause

pause circle fill

pause circle outline

play arrow

play circle fill

play circle outline

play shopping bag

playlist add

queue

queue music

radio

recent actors

repeat

repeat one

replay

shuffle

skip next

skip previous

snooze

stop

subtitles

surround sound

video collection

videocam

videocam off

volume down

volume mute

volume off

volume up

web

communication


business

call

call end

call made

call merge

call missed

call received

call split

chat

clear all

comment

contacts

dialer sip

dialpad

dnd on

email

forum

import export

invert colors off

invert colors on

live help

location off

location on

message

messenger

no sim

phone

portable wifi off

quick contacts dialer

quick contacts mail

ring volume

stay current landscape

stay current portrait

stay primary landscape

stay primary portrait

swap calls

textsms

voicemail

vpn key

content


add

add box

add circle

add circle outline

archive

backspace

block

clear

content copy

content cut

content paste

create

drafts

filter list

flag

forward

gesture

inbox

link

mail

markunread

redo

remove

remove circle

remove circle outline

reply

reply all

report

save

select all

send

sort

text format

undo

device


access alarm

access alarms

access time

add alarm

airplanemode off

airplanemode on

battery 20

battery 30

battery 50

battery 60

battery 80

battery 90

battery alert

battery charging 20

battery charging 30

battery charging 50

battery charging 60

battery charging 80

battery charging 90

battery charging full

battery full

battery std

battery unknown

bluetooth

bluetooth connected

bluetooth disabled

bluetooth searching

brightness auto

brightness high

brightness low

brightness medium

data usage

developer mode

devices

dvr

gps fixed

gps not fixed

gps off

location disabled

location searching

multitrack audio

network cell

network wifi

nfc

now wallpaper

now widgets

screen lock landscape

screen lock portrait

screen lock rotation

screen rotation

sd storage

settings system daydream

signal cellular 0 bar

signal cellular 1 bar

signal cellular 2 bar

signal cellular 3 bar

signal cellular 4 bar

signal cellular connected no internet 0 bar

signal cellular connected no internet 1 bar

signal cellular connected no internet 2 bar

signal cellular connected no internet 3 bar

signal cellular connected no internet 4 bar

signal cellular no sim

signal cellular null

signal cellular off

signal wifi 0 bar

signal wifi 1 bar

signal wifi 2 bar

signal wifi 3 bar

signal wifi 4 bar

signal wifi off

signal wifi statusbar 1 bar

signal wifi statusbar 2 bar

signal wifi statusbar 3 bar

signal wifi statusbar 4 bar

signal wifi statusbar connected no internet 1

signal wifi statusbar connected no internet

signal wifi statusbar connected no internet 2

signal wifi statusbar connected no internet 3

signal wifi statusbar connected no internet 4

signal wifi statusbar not connected

signal wifi statusbar null

storage

usb

wifi lock

wifi tethering

editor


attach file

attach money

border all

border bottom

border clear

border color

border horizontal

border inner

border left

border outer

border right

border style

border top

border vertical

format align center

format align justify

format align left

format align right

format bold

format clear

format color fill

format color reset

format color text

format indent decrease

format indent increase

format italic

format line spacing

format list bulleted

format list numbered

format paint

format quote

format size

format strikethrough

format textdirection l to r

format textdirection r to l

format underline

functions

insert chart

insert comment

insert drive file

insert emoticon

insert invitation

insert link

insert photo

merge type

mode comment

mode edit

publish

vertical align bottom

vertical align center

vertical align top

wrap text

file


attachment

cloud

cloud circle

cloud done

cloud download

cloud off

cloud queue

cloud upload

file download

file upload

folder

folder open

folder shared

hardware


cast

cast connected

computer

desktop mac

desktop windows

dock

gamepad

headset

headset mic

keyboard

keyboard alt

keyboard arrow down

keyboard arrow left

keyboard arrow right

keyboard arrow up

keyboard backspace

keyboard capslock

keyboard control

keyboard hide

keyboard return

keyboard tab

keyboard voice

laptop

laptop chromebook

laptop mac

laptop windows

memory

mouse

phone android

phone iphone

phonelink

phonelink off

security

sim card

smartphone

speaker

tablet

tablet android

tablet mac

tv

watch

image


add to photos

adjust

assistant photo

audiotrack

blur circular

blur linear

blur off

blur on

brightness 1

brightness 2

brightness 3

brightness 4

brightness 5

brightness 6

brightness 7

brush

camera

camera alt

camera front

camera rear

camera roll

center focus strong

center focus weak

collections

color lens

colorize

compare

control point

control point duplicate

crop 16 9

crop

crop 3 2

crop 5 4

crop 7 5

crop din

crop free

crop landscape

crop original

crop portrait

crop square

dehaze

details

edit

exposure

exposure minus 1

exposure minus 2

exposure plus 1

exposure plus 2

exposure zero

filter 1

filter

filter 2

filter 3

filter 4

filter 5

filter 6

filter 7

filter 8

filter 9

filter 9 plus

filter b and w

filter center focus

filter drama

filter frames

filter hdr

filter none

filter tilt shift

filter vintage

flare

flash auto

flash off

flash on

flip

gradient

grain

grid off

grid on

hdr off

hdr on

hdr strong

hdr weak

healing

image

image aspect ratio

iso

landscape

leak add

leak remove

lens

looks

looks 3

looks 4

looks 5

looks 6

looks one

looks two

loupe

movie creation

nature

nature people

navigate before

navigate next

palette

panorama

panorama fisheye

panorama horizontal

panorama vertical

panorama wide angle

photo

photo album

photo camera

photo library

portrait

remove red eye

rotate left

rotate right

slideshow

straighten

style

switch camera

switch video

tag faces

texture

timelapse

timer 10

timer

timer 3

timer auto

timer off

tonality

transform

tune

wb auto

wb cloudy

wb incandescent

wb irradescent

wb sunny

maps


beenhere

directions

directions bike

directions bus

directions car

directions ferry

directions subway

directions train

directions transit

directions walk

flight

hotel

layers

layers clear

local airport

local atm

local attraction

local bar

local cafe

local car wash

local convenience store

local drink

local florist

local gas station

local grocery store

local hospital

local hotel

local laundry service

local library

local mall

local movies

local offer

local parking

local pharmacy

local phone

local pizza

local play

local post office

local print shop

local restaurant

local see

local shipping

local taxi

location history

map

my location

navigation

pin drop

place

rate review

restaurant menu

satellite

store mall directory

terrain

traffic

navigation


apps

arrow back

arrow drop down

arrow drop down circle

arrow drop up

arrow forward

cancel

check

chevron left

chevron right

close

expand less

expand more

fullscreen

fullscreen exit

menu

more horiz

more vert

refresh

unfold less

unfold more

notification


adb

bluetooth audio

disc full

dnd forwardslash

do not disturb

drive eta

event available

event busy

event note

folder special

mms

more

network locked

phone bluetooth speaker

phone forwarded

phone in talk

phone locked

phone missed

phone paused

play download

play install

sd card

sim card alert

sms

sms failed

sync

sync disabled

sync problem

system update

tap and play

time to leave

vibration

voice chat

vpn lock

social


cake

domain

group

group add

location city

mood

notifications

notifications none

notifications off

notifications on

notifications paused

pages

party mode

people

people outline

person

person add

person outline

plus one

poll

public

school

share

whatshot

toggle


check box

check box outline blank

radio button off

radio button on

star

star half

star outline

同梱物は以下のようです.

SVG versions of all icons in both 24px and 48px flavours
SVG and CSS sprites of all icons
1x, 2x icons targeted at the Web (PNG)
1x, 2x, 3x icons targeted at iOS (PNG)
Hi-dpi versions of all icons (hdpi, mdpi, xhdpi, xxhdpi, xxxhdpi) (PNG)

あっ..