Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
はてなリモートインターン2021 Web API 講義資料
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Hatena
October 08, 2021
Technology
7.7k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
はてなリモートインターン2021 Web API 講義資料
https://hatenacorp.jp/recruit/intern/2021
Hatena
October 08, 2021
More Decks by Hatena
See All by Hatena
Androiderを育成する「高速道路」と 実戦を経て辿り着いた現在地 / DroidKaigi 2026
hatena
0
210
60分で学ぶクラウドとSRE・サービス運用 / GeekCAMPAcademia 2026-05
hatena
1
140
エンジニアリング マネージャーの育成と評価軸の考え方
hatena
0
740
Perlブートキャンプ
hatena
0
5.7k
はてなサマーインターンシップ2025 Web API 講義資料
hatena
0
1.8k
はてなサマーインターンシップ2025 フロントエンド 講義資料
hatena
21
11k
はてなサマーインターンシップ2025 コンテナ + Kubernetesハンズオン 講義資料
hatena
0
850
はてなサマーインターンシップ2025 クラウドと運用 講義資料
hatena
0
890
はてなサマーインターンシップ2025 RDBMSの基礎 講義資料
hatena
0
1k
Other Decks in Technology
See All in Technology
Tofu-Controller lightning talk @ Containerday 2026
gionn
0
120
LambdaWebFunctionsを試してみた / exploring-lambda-web-functions
koukihosaka
1
360
SAENM ~Jupyterで残すPoCの試行錯誤、未来の自分と仲間を助ける記録!~
terapyon
0
120
WasmをRustにする
sansantech
PRO
0
260
大型犬好きによるPugの紹介
yamanoku
1
160
Optunaの最新リリースv5.0について
pfn
PRO
0
120
1つのリクエストを追って理解する - llm-dのP/D分離
akhino
1
160
脆弱性診断って、何をしているの? 〜弱点を見つけて、会社の改善につなげるまで〜
keeg
0
930
スプシの手作業からの解脱 ~更新はClaude Codeに、見せ方と使い方はGASアプリに任せる~
kentarofujii
0
160
実践!Cloud Run ハンズオン!! / Cloud Run handson
y0hgi
2
290
今さら理解するウェブフォントver.2026
takanorip
3
890
Code for Security プロジェクト紹介 2026年10月
yu23ki14
0
110
Featured
See All Featured
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
330
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
Git: the NoSQL Database
bkeepers
PRO
433
67k
Making the Leap to Tech Lead
cromwellryan
135
10k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
550
Optimising Largest Contentful Paint
csswizardry
37
4k
Being A Developer After 40
akosma
92
590k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Google's AI Overviews - The New Search
badams
0
1.6k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Marketing to machines
jonoalderson
1
5.9k
Transcript
Web API IBUFOBJOUFSO
׆ס铺紶ךע ˝ )551 ˝ 3&45 ˝ (SBQI2- ˝ H31$
"1* "QQMJDBUJPO1SPHSBNNJOH*OUFSGBDF ˝ HMJCD ˝ document.getElementById ˝ GET https:!"api.twitter.com/1.1/statuses/ show.json?id=210462857140252672
)551 )ZQFSUFYU5SBOTGFS1SPUPDPM
)551סذّؕٚؕ٤ )551 )551 )551 (PPHMFֿ41%: 氦辐
(PPHMFֿ26*$ 氦辐 41%:⩕מג)551ס嘅嶖 )551PWFS26*$)551מ䷉ ⺲ 26*$ס嘅嶖
)551 ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM)551 ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM)551 ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM )551 .FTTBHF4ZOUBYBOE3PVUJOH ˝
3'$)ZQFSUFYU5SBOTGFS1SPUPDPM )551 4FNBOUJDTBOE$POUFOU ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM )551 $POEJUJPOBM3FRVFTUT ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM )551 3BOHF3FRVFTUT ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM )551 $BDIJOH ˝ 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM )551 "VUIFOUJDBUJPO
)551סجُ٤طؔؠت ˝ ْخشغכذ٭أشعٛؠؙتع ˝ تط٭ذتٝتَ٤ت ˝ ىشر٭ ˝ ٍظؔ
63- 6OJGPSN3FTPVSDF-PDBUPS https:!"localhost:8000/search?q=text#hello εΩʔϜ:!"ϗετ:ϙʔτ/ύε?ΫΤϦ#ϑϥάϝϯτ 8)"58(63--JWJOH4UBOEBSE
/FUDBUך)551ٛؠؙتع $ nc www.hatena.ne.jp 80 !" EOF GET / HTTP/1.1
Host: www.hatena.ne.jp EOF
HTTP/1.1 301 Moved Permanently Server: awselb/2.0 Date: Mon, 03 Aug
2020 01:58:38 GMT Content-Type: text/html Content-Length: 150 Connection: keep-alive Location: https:!"www.hatena.ne.jp:443/ <html> <head><title>301 Moved Permanently!#title>!#head> <body bgcolor="white"> <center><h1>301 Moved Permanently!#h1>!#center> !#body> !#html>
5-4ך䫘禈י)551ٛؠؙتع $ openssl s_client -connect www.hatena.ne.jp:443 HEAD / HTTP/1.1 Host:
www.hatena.ne.jp
)551 ٛؠؙتع METHOD target HTTP/1.1 Header: Value body ٝتَ٤ت HTTP/1.1
000 Reason Header: Value body
ٛؠؙتع车 METHOD target HTTP/1.1 GET POST PUT HEAD DELETE OPTIONS
TRACE CONNECT PATCH / /search?q=text HTTP/1.0 HTTP/1.1
ىشر٭ Host: www.hatena.ne.jp
تط٭ذت车 HTTP/1.1 000 Reason ˝ 1xx*OGPSNBUJPOBM ˝ 2xx4VDDFTTGVM ˝ 3xx3FEJSFDUJPO
˝ 4xx$MJFOU&SSPS ˝ 5xx4FSWFS&SSPS
ٍظؔ ˝ Content-Type: text/html˒)5.- ˝ Content-Type: application/JSON˒+40/ ˝ Content-Type: application/x-www-form-urlencoded
key=value&another_key=another_value
ٍظؔס㏆竊 Accept-Encoding: gzip, deflate Content-Encoding: gzip ˝ gzip ˝ compress
˝ deflate ˝ identity ˝ br
)551 3'$)ZQFSUFYU5SBOTGFS1SPUPDPM7FSTJPO )551
)551 ˝ 㓹儖氳םجُ٤طؔؠتע㚺םַ ˝ فؕػٛךכ ˝ ץכחס5$1ؤؾؠب٘٤♞䘶氳מ邾丗סتعٛ٭ّמ⮆Ⱏ ˝ تعٛ٭ّס╈ךنٝ٭ّ
˝ تعٛ٭ّס⨣⩝䈱❣㰆꞊➟辐杯ך׀
نٝ٭ّ +-----------------------------------------------+ | Length (24) | +---------------+---------------+---------------+ | Type (8)
| Flags (8) | +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0!!") !!" +---------------------------------------------------------------+ )ZQFSUFYU5SBOTGFS1SPUPDPM7FSTJPO )551 'SBNF'PSNBU
%"5"نٝ٭ّ0x0 +---------------+ |Pad Length? (8)| +---------------+-----------------------------------------------+ | Data (*) !!"
+---------------------------------------------------------------+ | Padding (*) !!" +---------------------------------------------------------------+ END_STREAM 0x1 ]PADDED 0x8
)&"%&34نٝ٭ّ0x1 +---------------+ |Pad Length? (8)| +-+-------------+-----------------------------------------------+ |E| Stream Dependency? (31)
| +-+-------------+-----------------------------------------------+ | Weight? (8) | +-+-------------+-----------------------------------------------+ | Header Block Fragment (*) !!" +---------------------------------------------------------------+ | Padding (*) !!" +---------------------------------------------------------------+ END_STREAM 0x1 ]END_HEADERS 0x4 ]PADDED 0x8 ]PRIORITY 0x20
橎⛍ىشر٭ ٛؠؙتع ˝ :method ˝ :authority ˝ :scheme ˝ :path
ٝتَ٤ت ˝ :status
)1"$, 3'$)1"$,)FBEFS$PNQSFTTJPOGPS)551 ˝ ـنُ٤瑞⺘ ˝ ꪐ氳ط٭هٜ ˝ Ⳃ氳ط٭هٜ
*OEFY )FBEFS/BNF )FBEFS7BMVF :authority :method GET :method
POST :path / :path /index.html :scheme http :scheme https :status 200
)551 ˝ )551סجُ٤طؔؠت禴䧏 ˝ ץכחס5$1ؤؾؠب٘٤邾丗סتعٛ٭ّמ⮆Ⱏ ˝ 邾丗סٛخ٭ت┉䈱מך׀ ˝ 邾ꥭם⯆䐒ֿך׀ ˝
ىشر٭㏆竊
)551 ˝ 26*$عٚ٤تَ٭ع ˝ 6%1┕מ5$1כ5-4ס嚀耆⫋杯 ˝ )551PWFS26*$ ˝ )55126*$عٚ٤تَ٭ع┕ך㲔逷 ˝
┘釐מםזג嚀耆⯡ꢜ ˝ 21"$,
)551PWFS26*$ ˝ 21"$, ˝ 瑞⺘םלյ㓹儖ע)1"$,כ⺱ ˝ Ⳃ氳ط٭هٜס䣽ַ亠ס㚺催 ˝ ꪐ氳ط٭هٜס㵚䑴ىشر鴑ⱶ
26*$ ˝ 3'$7FSTJPO*OEFQFOEFOU1SPQFSUJFTPG26*$ ˝ 3'$26*$"6%1#BTFE.VMUJQMFYFEBOE4FDVSF 5SBOTQPSU ˝ 3'$6TJOH5-4UP4FDVSF26*$ ˝ 3'$26*$-PTT%FUFDUJPOBOE$POHFTUJPO$POUSPM
ج؞ٖؓם26*$ ˝ 5-4 ˝ 355ـ٤غبؘؕؠמ냕鵭 &BSMZ%BUB ˝ 14, ◄⯥⪦鵟ꐶ ˝
ꐶס⫋⮵榫
ؤؾؠب٘٤ُؕءٝ٭ب٘٤ ˝ ⶡ┉סؾشع٠٭ؠقتמ䦔兠םַ ˝ ؙ٤غَؕ٤عסؓغٝتَ٭عֿ㚺催י䫘禈禴䧏 ך׀
ؓغٝتفٛظ٭ب٘٤ ˝ 鴜⟓⩕ؓغٝتֿ塜ַס־吾錞 ˝ عٚنؔشؠ㘃䆋䷍䱡 ؓ٤و䷍䱡 㵚瓀 ˝ 吾錞יַםַؓغٝتמ㵚יע鴜⟓ظ٭ذꄈ⯆
)551 ˝ 6%1┕מ5$1 5-4㲔杯 ˝ )5514מ鵟⟓ֿ⯥䬠 ˝ 355מⲖ曍 ˝ /"5ٛفؕ٤ظؔ٤ءמَ٭ع樑⺘㚺催םלֿ颯׀י䫘
禈ֿ禴䧏ך׀ ˝ ؓغٝت吾錞מؓ٤و䷍䱡㵚瓀
"1* "QQMJDBUJPO1SPHSBNNJOH*OUFSGBDF
-46%T -BSHF4FUPG6OLOPXO%FWFMPQFST ˝ 僃㛻⪜硜丗氳ם"1*䬠❠ 44,%T 4NBMM4FUPG,OPXO%FWFMPQFST ˝ ؠٚؕؓ٤عמ僃鸵ג"1*䬠❠
3&45 3FQSFTFOUBUJPOBM4UBUF5SBOTGFS ˝ )551ס☼磝ײֹױׂ✳ֹ ˝ ٛخ٭ت䧗⺸ https:!"api.github.com/repos/hatena/example/ issues/1
$36% )551ْخشغ $SFBUF POST 3FBE GET 6QEBUF PUTPATCH %FMFUF DELETE
(JU)VCסؕبٖ٭ؤْ٤ع ˝ GET /repos/:owner/:repo/issues/ comments/:comment_id ˝ POST /repos/:owner/:repo/issues/:issue_number/ comments ˝
PATCH /repos/:owner/:repo/issues/ comments/:comment_id ˝ DELETE /repos/:owner/:repo/issues/ comments/:comment_id
0QFO"1* ˝ 4XBHHFS ˝ 3&45"1*鋗鳭ג״ס☼喋 ˝ ؤ٭غ榟䡗מ✳ֻ
(SBQI2- ˝ 'BDFCPPLמזיꝧ氦ג ˝ ؠٚؕؓ٤ع⣐־䑒釐םنؔ٭ٜغ䧗㲊 ˝ ت؞٭ُ־סؤ٭غ榟䡗ֿך׀
4%- 4DIFNB%FOJUJPO-BOHVBHF interface Actor { login: String! } type Issue
{ author: Actor body: String! title: String! } type Repository { issue(number: Int!): Issue } type Query { repository(name: String!, owner: String!): Repository }
ؠؙٛ query GetFirstIssue { repository(name: "Hatena-Intern-2020", owner: "hatena") { issue(number:
1) { author { login } body title } } }
H31$
H31$PWFS)551 ˝ )551┕מ啶疣גס ˝ HEADERSنٝ٭ّDATAنٝ٭ّ H31$8FC ˝ 8FCهٚؗا⺸ׄמ)551כ⮉ꦕגס ˝ ئ٭ف٭⣐מوٞ؞بֿ䑒釐
1SPUPDPM#VFST ˝ 啶鵰גظ٭ذبٛؓٚؕث☼磝ײ ˝ فؕػٛنؚ٭ُشع ˝ *%- *OUFSGBDF%FTDSJQUJPO-BOHVBHF ˝ .protoنٜؒؕ
˝ 31$ئَ٭عיַ
syntax = "proto3"; package account; service Account { rpc Signup(SignupRequest)
returns (SignupReply); } message SignupRequest { string name = 1; string password = 2; } message SignupReply { string token = 1; }
ْشج٭ة㑔 message SignupRequest { string name = 1; string password
= 2; } ϑΟʔϧυܕ ϑΟʔϧυ໊ = ϑΟʔϧυ൪߸; ˝ نؔ٭ٜغ樑⺘ֿꄆ釐 ˝ ױךעCZUF ˝ ע◀硜岷ײ
تٚ٭㑔 double float int32 int64 uint32 uint64 sint32 sint64 fixed32
fixed64 sfixed32 sfixed64 bool string bytes
repeated Result results = 1; map<string, Project> projects = 3;
oneof test_oneof { string name = 4; SubMessage sub_message = 9; }
message SearchRequest { string query = 1; int32 page_number =
2; int32 result_per_page = 3; enum Corpus { UNIVERSAL = 0; WEB = 1; IMAGES = 2; LOCAL = 3; NEWS = 4; PRODUCTS = 5; VIDEO = 6; } Corpus corpus = 4; }
import "google/protobuf/any.proto"; message Message { google.protobuf.Any field = 1; }
˝ google.protobuf.Empty ˝ google.protobuf.Duration ˝ google.protobuf.Timestamp
◍䬵䓪 ˝ نؔ٭ٜغ樑⺘ int32 old_field = 6 [deprecated = true];
reserved 2, 15, 9 to 11; reserved "foo", "bar";
؛وب٘٤ option go_package = "github.com/hatena/example/pb"; enum EnumAllowingAlias { option allow_alias
= true; UNKNOWN = 0; STARTED = 1; RUNNING = 1; } message Example { int32 old_field = 6 [deprecated = true]; }
ئ٭لتכتعٛ٭ّ service RouteGuide { rpc GetFeature(Point) returns (Feature) {} rpc
ListFeatures(Rectangle) returns (stream Feature) {} rpc RecordRoute(stream Point) returns (RouteSummary) {} rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} }
H31$מֽׄ"1*錃銶 $36% -JTU ˝ CreateEntity ˝ GetEntity ˝ UpdateEntity ˝
DeleteEntity ˝ ListEntities
$MPVE'VODUJPOTס❆ ˝ CallFunction ˝ CreateFunction ˝ GetFunction ˝ UpdateFunction ˝
DeleteFunction ˝ ListFunctions
H31$ئ٭ف٭⛼
syntax = "proto3"; option go_package = "./pb"; package welcome; service
Welcome { rpc Greet(GreetRequest) returns (GreetReply); } message GreetRequest { string name = 1; } message GreetReply { string message = 1; }
1SPUPDPM$PNQJMFS protoc $ # protoc brew install protobuf
apt install protobuf-compiler ͳͲͰ $ go install google.golang.org/protobuf/cmd/protoc-gen-go $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc $ protoc !"go_out=. !"go-grpc_out=. welcome.proto
package main import ( "context" "flag" "fmt" "github.com/hatena/intern-grpc/pb" "google.golang.org/grpc" "google.golang.org/grpc/reflection"
"log" "net" "os" "os/signal" ) var ( port = flag.Int("port", 10000, "The server port") )
type welcomeServer struct { pb.UnimplementedWelcomeServer } func (s *welcomeServer) Greet(
ctx context.Context, req *pb.GreetRequest ) (*pb.GreetReply, error) { return &pb.GreetReply{ Message: fmt.Sprintf("Welcome %s", req.Name), }, nil } func newServer() *welcomeServer { return &welcomeServer{} }
func main() { lis, err !" net.Listen("tcp", fmt.Sprintf(":%d", *port)) if
err !# nil { log.Fatalf("failed to listen: %v", err) } grpcServer !" grpc.NewServer() pb.RegisterWelcomeServer(grpcServer, newServer()) reflection.Register(grpcServer) go func() { log.Printf("start gRPC server port: %v", *port) grpcServer.Serve(lis) }() quit !" make(chan os.Signal) signal.Notify(quit, os.Interrupt) !$quit log.Printf("stopping gRPC server!!%") grpcServer.GracefulStop() }
-FU˖TUSZgrpc_cli
grpc_cli $ docker run !"rm !"publish 10000:10000 hatena/intern-2020-grpc-adventure:latest $ docker
run !"rm hatena/grpc_cli:latest ls host.docker.internal:10000 -l
grpc_cli $ grpc_cli ls localhost:10000 -l $ grpc_cli type localhost:10000
welcome.GreetRequest $ grpc_cli call localhost:10000 welcome.Welcome.Greet 'name: "John Appleseed"'