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
はてなリモートインターン2020 Web API 講義資料
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Hatena
May 31, 2022
170
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
はてなリモートインターン2020 Web API 講義資料
https://hatenacorp.jp/intern2020/public_broadcast
Hatena
May 31, 2022
More Decks by Hatena
See All by Hatena
Androiderを育成する「高速道路」と 実戦を経て辿り着いた現在地 / DroidKaigi 2026
hatena
0
43
60分で学ぶクラウドとSRE・サービス運用 / GeekCAMPAcademia 2026-05
hatena
1
110
エンジニアリング マネージャーの育成と評価軸の考え方
hatena
0
680
Perlブートキャンプ
hatena
0
5.3k
はてなサマーインターンシップ2025 Web API 講義資料
hatena
0
1.7k
はてなサマーインターンシップ2025 フロントエンド 講義資料
hatena
21
11k
はてなサマーインターンシップ2025 コンテナ + Kubernetesハンズオン 講義資料
hatena
0
830
はてなサマーインターンシップ2025 クラウドと運用 講義資料
hatena
0
870
はてなサマーインターンシップ2025 RDBMSの基礎 講義資料
hatena
0
940
Featured
See All Featured
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
450
Build your cross-platform service in a week with App Engine
jlugia
234
19k
The SEO Collaboration Effect
kristinabergwall1
1
550
エンジニアに許された特別な時間の終わり
watany
108
250k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Google's AI Overviews - The New Search
badams
0
1.6k
The World Runs on Bad Software
bkeepers
PRO
72
12k
How STYLIGHT went responsive
nonsquared
100
6.3k
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Accessibility Awareness
sabderemane
1
210
Mind Mapping
helmedeiros
1
350
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
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ח何せ
)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"$,
"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 $ go get github.com/golang/protobuf/protoc-gen-go $ protoc welcome.proto !"go_out=plugins=grpc:.
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"'