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
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
170
60分で学ぶクラウドとSRE・サービス運用 / GeekCAMPAcademia 2026-05
hatena
1
140
エンジニアリング マネージャーの育成と評価軸の考え方
hatena
0
720
Perlブートキャンプ
hatena
0
5.7k
はてなサマーインターンシップ2025 Web API 講義資料
hatena
0
1.8k
はてなサマーインターンシップ2025 フロントエンド 講義資料
hatena
21
11k
はてなサマーインターンシップ2025 コンテナ + Kubernetesハンズオン 講義資料
hatena
0
840
はてなサマーインターンシップ2025 クラウドと運用 講義資料
hatena
0
880
はてなサマーインターンシップ2025 RDBMSの基礎 講義資料
hatena
0
1k
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
460
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
A better future with KSS
kneath
240
18k
How to make the Groovebox
asonas
2
2.5k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
260
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Navigating Weather and Climate Data
rabernat
0
550
Amusing Abliteration
ianozsvald
1
320
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
250
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"'