Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
はてなリモートインターン2020 Web API 講義資料
Hatena
May 31, 2022
0
53
はてなリモートインターン2020 Web API 講義資料
https://hatenacorp.jp/intern2020/public_broadcast
Hatena
May 31, 2022
Tweet
Share
More Decks by Hatena
See All by Hatena
はてなリモートインターンシップ2022 Kubernetes 講義資料
hatena
0
86
はてなリモートインターンシップ2022 フロントエンドブートキャンプ 講義資料
hatena
0
110
はてなリモートインターンシップ2022 RDBMSブートキャンプ 講義資料
hatena
0
78
はてなリモートインターンシップ2022 Web API 講義資料
hatena
0
150
はてなリモートインターンシップ2022 インフラ 講義資料
hatena
4
2.1k
はてなリモートインターンシップ2022 マイクロサービス 講義資料
hatena
0
82
はてなリモートインターンシップ2022 コンテナ 講義資料
hatena
0
83
はてなの選考設計、その深奥に迫る! / Recruiment Process Deep Dive Seminar #22
hatena
1
760
はてなのカジュアル面談FAQ / Hatena Engineer Seminar #22 wtatsuru
hatena
0
670
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
59
5.7k
Bootstrapping a Software Product
garrettdimon
299
110k
KATA
mclloyd
12
9.7k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
2
390
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
13
1.1k
Building Flexible Design Systems
yeseniaperezcruz
314
35k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
152
13k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
63k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
13
5.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
22
1.4k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
38
3.6k
Making Projects Easy
brettharned
102
4.8k
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"'