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

はてなインターンシップ2024 HTTP, Web, API 講義資料

Hatena
October 31, 2024
110

はてなインターンシップ2024 HTTP, Web, API 講義資料

Hatena

October 31, 2024
Tweet

Transcript

  1. import OpenAI from "openai"; const client = new OpenAI(); async

    function main() { const stream = await client.chat.completions.create({ model: "gpt-4", messages: [ { role: "user", content: "Πϯλʔωοτ࠷ߴʁ͸͍͔͍͍͑Ͱ౴͑ͯɻ" }, ], stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content || ""); } } main(); IBUFOBJOUFSO !
  2. ϓϩτίϧ • = 約束ごと • TCP/IP, HTTP, DNS, TLS, SMTP,

    3 • インターネットの参加者はプロトコルに従っている • サーバ(Google やはてな) • クライアント(ブラウザ、スマートフォンアプリ) • ルータ、… • これらのプロトコルは RFC によって定義される • = Request for Comments IBUFOBJOUFSO !
  3. HTTP ͷλΠϜϥΠϯ 1991 HTTP/%.' 1996 HTTP/%.' 1997 HTTP/%.% 2009 Google

    が SPDY を発表 2013 Google が QUIC を発表 2015 SPDY を元にしたHTTP/%の 標準化 2018 HTTP-over-QUIC を HTTP/%に改名 2021 QUIC の標準化 2022 HTTP/% の標準化 IBUFOBJOUFSO !
  4. HTTP/1.1: HTTP ͷجૅ • RFC &''(: HTTP Semantics • RFC

    &''': HTTP Caching • RFC &''8: HTTP/'.' • Deprecated: • RFC 8(?@ Hypertext Transfer Protocol -- HTTP/'.' • RFC 8?'? Hypertext Transfer Protocol -- HTTP/'.' • RFC G8H( Hypertext Transfer Protocol (HTTP/'.'): Message Syntax and Routing • RFC G8H' Hypertext Transfer Protocol (HTTP/'.'): Semantics and Content • RFC G8H8 Hypertext Transfer Protocol (HTTP/'.'): Conditional Requests • RFC G8HH Hypertext Transfer Protocol (HTTP/'.'): Range Requests • RFC G8HN Hypertext Transfer Protocol (HTTP/'.'): Caching • RFC G8HO Hypertext Transfer Protocol (HTTP/'.'): Authentication IBUFOBJOUFSO !"
  5. Uniform Resource Locator (URL) • ブラウザで「開く」と… • HTTP(S) でリソースを取得する •

    motemen.hatenablog.com の 443 ポート • /search?q=git • データ (HTML) を解釈して表⽰する IBUFOBJOUFSO !!
  6. HTTP/1.1 301 Moved Permanently Server: CloudFront Date: Tue, 06 Aug

    2024 15:05:29 GMT Content-Type: text/html Content-Length: 167 Connection: keep-alive Location: https://hatena.blog/ X-Cache: Redirect from cloudfront Via: 1.1 8c817b46442ccacdcf3e583dbee62638.cloudfront.net (CloudFront) X-Amz-Cf-Pop: KIX56-P3 X-Amz-Cf-Id: ELtBOsBNUbrwkgpoiVQpEqXNxcOEmWWlcDPIIf31oudnwEgn9MNysw== <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>CloudFront</center> </body> </html> IBUFOBJOUFSO !"
  7. HTTPS ΋஻ͬͯΈΔ • HTTP over TLS • https://hatena.blog/ へのアクセス $

    openssl s_client -connect hatena.blog:443 GET / HTTP/1.1 Host: hatena.blog ↵ IBUFOBJOUFSO !"
  8. HTTP ͷεΠεΞʔϛʔφΠϑ: curl $ curl --head --location --verbose http://hatena.blog/ >

    HEAD / HTTP/1.1 > Host: hatena.blog > User-Agent: curl/8.6.0 > Accept: */* > < HTTP/1.1 301 Moved Permanently ... curl --help all で楽しもう IBUFOBJOUFSO !"
  9. HTTP/1.1 γϯλοΫε ϦΫΤετ <method> <target> HTTP/1.1 <field>: <value> <body> Ϩεϙϯε

    HTTP/1.1 000 <reason> <field>: <value> <body> IBUFOBJOUFSO !"
  10. ϦΫΤετߦ <method> <target> HTTP/1.1 GET POST PUT HEAD DELETE OPTIONS

    TRACE CONNECT PATCH /entry/1 /search?q=text / HTTP/1.0 HTTP/1.1 IBUFOBJOUFSO !"
  11. εςʔλεߦ HTTP/1.1 000 Reason • 1xx Informational • 2xx Successful

    • 3xx Redirection • 4xx Client Error • 5xx Server Error IBUFOBJOUFSO !"
  12. ϘσΟ HTML <!DOCTYPE html> <html lang="ja"> ... JSON { "id":

    "42", "created": 1723707520, ... } PNG ը૾ ?PNG\0d\1a\00\00\00\0dIHDR... IBUFOBJOUFSO !"
  13. ϔομʔ Host: hatena.blog Content-Type: text/html Content-Length: 167 Location: https://hatena.blog/ •

    メッセージを拡張したり、メタデータとして機能したり IBUFOBJOUFSO !"
  14. Content-Type • Content-Type: text/html — HTML • Content-Type: application/json —

    JSON • Content-Type: image/png — PNG 画像 IBUFOBJOUFSO !!
  15. ίϯςϯτωΰγΤʔγϣϯ 同じ URL へのアクセスでも… • Accept: text/html • リンク遷移など •

    Accept: image/* • <img> 要素からのリクエストなど IBUFOBJOUFSO !"
  16. Server-Sent Events • Content-Type: text/event-stream • サーバ側からプッシュ形式でデータをクライアントに送信す る var source

    = new EventSource("updates.cgi"); source.onmessage = function (event) { alert(event.data); }; IBUFOBJOUFSO !"
  17. ϘσΟͷѹॖ • クライアント Accept-Encoding: gzip, deflate • サーバ Content-Encoding: gzip

    • gzip • compress • deflate • identity • br IBUFOBJOUFSO !"
  18. ΫοΩʔ ! • サーバ Set-Cookie: key=value; Expires=Wed, 09 Jun 2024

    10:18:14 GMT • クライアント Cookie: key=value • HTTP は本来ステートレス → 「セッション」の導⼊ • ブラウザにクッキーを⾷べさせることで次回以降のリクエストに情 報を持ち越す IBUFOBJOUFSO !"
  19. HTTP/1.1 ͷ໰୊఺ • 背景: 複雑化する Web アプリケーション環境 • たくさんのアセット (JavaScript、画像、…)

    • モバイル機器からのアクセス • リクエスト-レスポンスのやりとりが TCP コネクションを専有 • ドメインあたりのコネクションは 6 つほどに制限されている • 「重い」リクエストがあると次のリクエストができない • ヘッダーの冗⻑性 IBUFOBJOUFSO !"
  20. HTTP/2 • セマンティクスは HTTP//./ と共通 • バイナリフレームでやりとり • ひとつの TCP

    コネクションを複数のストリームに分割 • 複数のリソースを⼀度にやり取りできる • 複雑な制御ができる • ヘッダーも圧縮 IBUFOBJOUFSO !"
  21. HPACK RFC %&'( HPACK: Header Compression for HTTP/; Index Header

    Name Header Value / :authority 0 :method GET 1 :method POST 2 :path / 3 :path /index.html 4 :scheme http 5 :scheme https 6 :status 200 IBUFOBJOUFSO !"
  22. HTTP/3 • QUIC トランスポート • UDP 上に TCP と TLS

    の機能を再現 • HTTP-over-QUIC • HTTP/B を QUIC トランスポート上で実装 • QPACK • コネクションマイグレーション $ open https://http3.is IBUFOBJOUFSO !!
  23. HTTP • セマンティクス • HTTP/-.- • シンタックス • HTTP/2, HTTP/5

    • モチベーション • 仕組み IBUFOBJOUFSO !"
  24. Application Programming Interface • OS ⇔ アプリケーション • glibc: システムコール

    • ブラウザ ⇔ JavaScript アプリケーション • DOM (Document Object Model): HTML ⽂書を JS から操作 • Web サービス ⇔ Web フロントエンド、アプリ、別システム • REST • GraphQL • gRPC IBUFOBJOUFSO !"
  25. LSUDs (Large Set of Unknown Developers) • 最⼤公約数的な API を提供する

    SSKDs (Small Set of Known Developers) • クライアントに最適化した API を提供する IBUFOBJOUFSO !"
  26. CRUD HTTP メソッド Create POST Read GET Update PUT /

    PATCH Delete DELETE IBUFOBJOUFSO !"
  27. ྫ: GitHub ͷΠγϡʔίϝϯτ • POST /repos/:owner/:repo/issues/:issue_number/comments • GET /repos/:owner/:repo/issues/comments/:comment_id •

    PATCH /repos/:owner/:repo/issues/comments/:comment_id • DELETE /repos/:owner/:repo/issues/comments/:comment_id ྫ: OpenAI ͷϑΝΠϯνϡʔχϯά • POST /v1/fine_tuning/jobs • GET /v1/fine_tuning/jobs/{fine_tuning_job_id} • POST /v1/fine_tuning/jobs/{fine_tuning_job_id}/cancel IBUFOBJOUFSO !"
  28. REST ͷಛ௃ • 実装や原則がシンプル • 道具なく作りはじめられる • REST「⾵」になりがちではある • クライアント側から使いにくくなりがち

    • オーバーフェッチ、アンダーフェッチ • 要求の変化への対応が難しくなりがち IBUFOBJOUFSO !"
  29. SDL (Schema Definition Language) type Query { blog(id: String!): Blog

    } type Blog { title: String! entries(first: Int!): [Entry!] } type Entry { title: String! body: String! name: String @deprecated(reason: "Use `title`.") } IBUFOBJOUFSO !!
  30. ྫ: GitHub API ΁ͷΫΤϦ $ gh api graphql --verbose -f

    query='query { viewer { login repositories(last: 3, visibility: PUBLIC) { nodes { name } } } }' { "data": { "viewer": { "login": "motemen", "repositories": { "nodes": [ { "name": "pokemon-data" }, { "name": "pamo3-card-to-pokesol-text" }, { "name": "macos-obs-websocket-ocr" } ] } } } } IBUFOBJOUFSO !"
  31. πʔϧηοτͷαϙʔτ • サーバ • スキーマからのコード⽣成 • リゾルバの実装 • クライアント •

    UI ライブラリとの連携 • 型定義の⽣成 • キャッシュの管理 • GraphiQL IBUFOBJOUFSO !"
  32. gRPC • Google によって開発された • RPC (Remote Procedure Call) のためのシステム

    • 定義ファイルからのコード⽣成 • HTTP/S ベース • 双⽅向ストリーミングもサポート IBUFOBJOUFSO !"
  33. syntax = "proto3"; package account; service Account { rpc Signup(SignupRequest)

    returns (SignupReply); } message SignupRequest { string name = 1; string password = 2; } message SignupReply { string token = 1; } IBUFOBJOUFSO !"
  34. ϝοηʔδܕ message SignupRequest { string name = 1; string password

    = 2; } ϑΟʔϧυܕ ϑΟʔϧυ໊ = ϑΟʔϧυ൪߸; • フィールド番号が重要 IBUFOBJOUFSO !"
  35. ޓ׵ੑ • フィールド番号 int32 old_field = 6 [deprecated = true];

    reserved 2, 15, 9 to 11; reserved "foo", "bar"; IBUFOBJOUFSO !"
  36. gRPC ʹ͓͚Δ API ઃܭ CRUD + List • CreateEntity •

    GetEntity • UpdateEntity • DeleteEntity • ListEntities IBUFOBJOUFSO !"
  37. 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; } IBUFOBJOUFSO !!
  38. Protocol Compiler protoc $ brew install protobuf # for protoc

    $ 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 IBUFOBJOUFSO !"
  39. 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") ) IBUFOBJOUFSO !"
  40. 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{} } IBUFOBJOUFSO !"
  41. 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() } IBUFOBJOUFSO !"
  42. grpcurl $ docker compose up grpc_server-1 | 2024/08/06 14:47:05 start

    gRPC server port: 10000 $ grpcurl -plaintext localhost:10000 list grpc.reflection.v1.ServerReflection grpc.reflection.v1alpha.ServerReflection welcome.Welcome IBUFOBJOUFSO !"
  43. grpcurl $ grpcurl -plaintext localhost:10000 describe welcome.Welcome welcome.Welcome is a

    service: service Welcome { rpc Greet ( .welcome.GreetRequest ) returns ( .welcome.GreetReply ); } $ grpcurl -plaintext localhost:10000 describe welcome.GreetRequest welcome.GreetRequest is a message: message GreetRequest { string name = 1; } $ grpcurl -plaintext -d '{"name":"motemen"}' localhost:10000 welcome.Welcome.Greet { "message": "Welcome motemen" } IBUFOBJOUFSO !"
  44. API • いくつかの API について⾒てきた • REST • GraphQL •

    gRPC • 特徴とトレードオフを理解して使おう IBUFOBJOUFSO !"