Upgrade to Pro — share decks privately, control downloads, hide ads and more …

はてなリモートインターン2020 Web API 講義資料

Hatena
May 31, 2022
76

はてなリモートインターン2020 Web API 講義資料

Hatena

May 31, 2022
Tweet

More Decks by Hatena

Transcript

  1. Web API
    IBUFOBJOUFSO

    View Slide

  2. ֿך闌纏דכ
    ˖ )551
    ˖ 3&45
    ˖ (SBQI2-
    ˖ H31$

    View Slide

  3. "1*
    "QQMJDBUJPO1SPHSBNNJOH*OUFSGBDF
    ˖ HMJCD
    ˖ document.getElementById
    ˖ GET https:!"api.twitter.com/1.1/statuses/
    show.json?id=210462857140252672

    View Slide

  4. )551
    )ZQFSUFYU5SBOTGFS1SPUPDPM

    View Slide

  5. )551ךة؎يٓ؎ٝ

    )551

    )551

    )551

    (PPHMFָ41%:׾
    涪邌

    (PPHMFָ26*$׾
    涪邌

    41%:׾⯋ח׃׋
    )551ך垥彊⻉

    )551PWFS26*$
    ׾)551ח何せ

    View Slide

  6. )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

    View Slide

  7. )551ךإوٝذ؍ؙأ
    ˖ ًاحسהة٦؜حزؙٔؒأز
    ˖ أذ٦ةأٖأهٝأ
    ˖ قحت٦
    ˖ نر؍

    View Slide

  8. 63-
    6OJGPSN3FTPVSDF-PDBUPS
    https:!"localhost:8000/search?q=text#hello
    εΩʔϜ:!"ϗετ:ϙʔτ/ύε?ΫΤϦ#ϑϥάϝϯτ
    8)"58(63--JWJOH4UBOEBSE

    View Slide

  9. /FUDBUד)551ؙٔؒأز
    $ nc www.hatena.ne.jp 80 !" EOF
    GET / HTTP/1.1
    Host: www.hatena.ne.jp
    EOF

    View Slide

  10. 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/

    301 Moved Permanently!#title>!#head>

    301 Moved Permanently!#h1>!#center>
    !#body>
    !#html>

    View Slide

  11. 5-4ד䱸竲׃ג)551ؙٔؒأز
    $ openssl s_client -connect www.hatena.ne.jp:443
    HEAD / HTTP/1.1
    Host: www.hatena.ne.jp

    View Slide

  12. )551
    ؙٔؒأز
    METHOD target HTTP/1.1
    Header: Value
    body
    ٖأهٝأ
    HTTP/1.1 000 Reason
    Header: Value
    body

    View Slide

  13. ؙٔؒأز遤
    METHOD target HTTP/1.1
    GET
    POST
    PUT
    HEAD
    DELETE
    OPTIONS
    TRACE
    CONNECT
    PATCH
    /
    /search?q=text
    HTTP/1.0
    HTTP/1.1

    View Slide

  14. قحت٦
    Host: www.hatena.ne.jp

    View Slide

  15. أذ٦ةأ遤
    HTTP/1.1 000 Reason
    ˖ 1xx*OGPSNBUJPOBM
    ˖ 2xx4VDDFTTGVM
    ˖ 3xx3FEJSFDUJPO
    ˖ 4xx$MJFOU&SSPS
    ˖ 5xx4FSWFS&SSPS

    View Slide

  16. نر؍
    ˖ Content-Type: text/htmlˋ)5.-
    ˖ Content-Type: application/JSONˋ+40/
    ˖ Content-Type: application/x-www-form-urlencoded
    key=value&another_key=another_value

    View Slide

  17. نر؍ך㖇簭
    Accept-Encoding: gzip, deflate
    Content-Encoding: gzip
    ˖ gzip
    ˖ compress
    ˖ deflate
    ˖ identity
    ˖ br

    View Slide

  18. )551
    3'$)ZQFSUFYU5SBOTGFS1SPUPDPM7FSTJPO )551

    View Slide

  19. )551
    ˖ 㛇劤涸זإوٝذ؍ؙأכ㢌׻׵זְ
    ˖ غ؎شٔדװ׶ה׶ׅ׷
    ˖ מהאך5$1؝طؙءّٝ׾⟎䟝涸ח醱侧ךأزٔ٦يחⴓⶴ
    ׅ׷
    ˖ أزٔ٦يך⚥דؿٖ٦ي׾װ׶《׶ׅ׷
    ˖ أزٔ٦يך⮚⯓䏝װ⣛㶷ꟼ⤘׮邌植דֹ׷

    View Slide

  20. ؿٖ٦ي
    +-----------------------------------------------+
    | Length (24) |
    +---------------+---------------+---------------+
    | Type (8) | Flags (8) |
    +-+-------------+---------------+-------------------------------+
    |R| Stream Identifier (31) |
    +=+=============================================================+
    | Frame Payload (0!!") !!"
    +---------------------------------------------------------------+
    )ZQFSUFYU5SBOTGFS1SPUPDPM7FSTJPO )551
    'SBNF'PSNBU

    View Slide

  21. %"5"ؿٖ٦ي0x0
    +---------------+
    |Pad Length? (8)|
    +---------------+-----------------------------------------------+
    | Data (*) !!"
    +---------------------------------------------------------------+
    | Padding (*) !!"
    +---------------------------------------------------------------+
    END_STREAM 0x1
    ]PADDED 0x8

    View Slide

  22. )&"%&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

    View Slide

  23. 毟⡂قحت٦
    ؙٔؒأز
    ˖ :method
    ˖ :authority
    ˖ :scheme
    ˖ :path
    ٖأهٝأ
    ˖ :status

    View Slide

  24. )1"$,
    3'$)1"$,)FBEFS$PNQSFTTJPOGPS)551
    ˖ عؿوٝ痗〾
    ˖ ꫼涸ذ٦ـٕ
    ˖ ⹛涸ذ٦ـٕ

    View Slide

  25. *OEFY )FBEFS/BNF )FBEFS7BMVF
    :authority
    :method GET
    :method POST
    :path /
    :path /index.html
    :scheme http
    :scheme https
    :status 200

    View Slide

  26. )551
    ˖ )551ךإوٝذ؍ؙأ׾笝䭯
    ˖ מהאך5$1؝طؙءّٝ׾醱侧ךأزٔ٦يחⴓⶴ
    ˖ 醱侧ךٔا٦أ׾♧䏝חװ׶《׶דֹ׷
    ˖ 醱꧟זⵖ䖴ָדֹ׷
    ˖ قحت٦׮㖇簭

    View Slide

  27. )551
    ˖ 26*$زٓٝأه٦ز
    ˖ 6%1♳ח5$1ה5-4ך堣腉׾ⱄ植
    ˖ )551PWFS26*$
    ˖ )551׾26*$زٓٝأه٦ز♳ד㹋鄲
    ˖ ♶銲חז׏׋堣腉׾⵴ꤐ
    ˖ 21"$,

    View Slide

  28. "1*
    "QQMJDBUJPO1SPHSBNNJOH*OUFSGBDF

    View Slide

  29. -46%T -BSHF4FUPG6OLOPXO%FWFMPQFST

    ˖ 剑㣐Ⱅ秈侧涸ז"1*׾䲿⣘ׅ׷
    44,%T 4NBMM4FUPG,OPXO%FWFMPQFST

    ˖ ؙٓ؎،ٝزח剑黝⻉׃׋"1*׾䲿⣘ׅ׷

    View Slide

  30. 3&45
    3FQSFTFOUBUJPOBM4UBUF5SBOTGFS
    ˖ )551ך➬穈׫׾ֲתֻ⢪ֲ
    ˖ ٔا٦أ䭷ぢ
    https:!"api.github.com/repos/hatena/example/
    issues/1

    View Slide

  31. $36%
    )551ًاحس
    $SFBUF POST
    3FBE GET
    6QEBUF PUTPATCH
    %FMFUF DELETE

    View Slide

  32. (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

    View Slide

  33. 0QFO"1*
    ˖ 4XBHHFS
    ˖ 3&45"1*׾鎸鶢ׅ׷׋׭ך➬圫
    ˖ ؝٦س欰䧭ח׮⢪ִ׷

    View Slide

  34. (SBQI2-
    ˖ 'BDFCPPLח״׏גꟚ涪ׁ׸׋
    ˖ ؙٓ؎،ٝز⩎ַ׵䗳銲זؿ؍٦ٕس׾䭷㹀ׅ׷
    ˖ أؗ٦وַ׵ך؝٦س欰䧭ָדֹ׷

    View Slide

  35. 4%- 4DIFNB%FOJUJPO-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
    }

    View Slide

  36. ؙؒٔ
    query GetFirstIssue {
    repository(name: "Hatena-Intern-2020", owner: "hatena") {
    issue(number: 1) {
    author {
    login
    }
    body
    title
    }
    }
    }

    View Slide

  37. H31$

    View Slide

  38. H31$PWFS)551
    ˖ )551♳ח圓眠ׁ׸׋׮ך
    ˖ HEADERSؿٖ٦يװDATAؿٖ٦ي
    H31$8FC
    ˖ 8FCـٓؐؠぢֽח)551הⴖ׶ꨄ׃׋׮ך
    ˖ ؟٦غ٦⩎ח׮فٗؗءָ䗳銲

    View Slide

  39. 1SPUPDPM#VFST
    ˖ 圓鸡⻉ׁ׸׋ر٦ة׾ءٔ،ٓ؎ؤׅ׷➬穈׫
    ˖ غ؎شٔؿؓ٦وحز
    ˖ *%- *OUFSGBDF%FTDSJQUJPO-BOHVBHF

    ˖ .protoؿ؋؎ٕ
    ˖ 31$׾؟ه٦ز׃גְ׷

    View Slide

  40. syntax = "proto3";
    package account;
    service Account {
    rpc Signup(SignupRequest) returns (SignupReply);
    }
    message SignupRequest {
    string name = 1;
    string password = 2;
    }
    message SignupReply {
    string token = 1;
    }

    View Slide

  41. ًحإ٦آ㘗
    message SignupRequest {
    string name = 1;
    string password = 2;
    }
    ϑΟʔϧυܕ ϑΟʔϧυ໊ = ϑΟʔϧυ൪߸;
    ˖ ؿ؍٦ٕس殢〾ָꅾ銲
    ˖ תדכCZUF
    ˖ כ✮秈幥׫

    View Slide

  42. أؕٓ٦㘗
    double
    float
    int32
    int64
    uint32
    uint64
    sint32
    sint64
    fixed32
    fixed64
    sfixed32
    sfixed64
    bool string
    bytes

    View Slide

  43. repeated Result results = 1;
    map projects = 3;
    oneof test_oneof {
    string name = 4;
    SubMessage sub_message = 9;
    }

    View Slide

  44. 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;
    }

    View Slide

  45. import "google/protobuf/any.proto";
    message Message {
    google.protobuf.Any field = 1;
    }
    ˖ google.protobuf.Empty
    ˖ google.protobuf.Duration
    ˖ google.protobuf.Timestamp

    View Slide

  46. ✼䳔䚍
    ˖ ؿ؍٦ٕس殢〾
    int32 old_field = 6 [deprecated = true];
    reserved 2, 15, 9 to 11;
    reserved "foo", "bar";

    View Slide

  47. ؔفءّٝ
    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];
    }

    View Slide

  48. ؟٦ؽأהأزٔ٦ي
    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) {}
    }

    View Slide

  49. H31$חֶֽ׷"1*鏣鎘
    $36%-JTU
    ˖ CreateEntity
    ˖ GetEntity
    ˖ UpdateEntity
    ˖ DeleteEntity
    ˖ ListEntities

    View Slide

  50. $MPVE'VODUJPOTך⢽
    ˖ CallFunction
    ˖ CreateFunction
    ˖ GetFunction
    ˖ UpdateFunction
    ˖ DeleteFunction
    ˖ ListFunctions

    View Slide

  51. H31$؟٦غ٦׾⡲׷

    View Slide

  52. 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;
    }

    View Slide

  53. 1SPUPDPM$PNQJMFS
    protoc
    $ go get github.com/golang/protobuf/protoc-gen-go
    $ protoc welcome.proto !"go_out=plugins=grpc:.

    View Slide

  54. 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")
    )

    View Slide

  55. 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{}
    }

    View Slide

  56. 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()
    }

    View Slide

  57. -FUˏTUSZgrpc_cli

    View Slide

  58. 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

    View Slide

  59. 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"'

    View Slide