document.getElementById
GET https:!"api.twitter.com/1.1/statuses/
show.json?id=210462857140252672
https:!"localhost:8000/search?q=text#hello
$ 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>
$ openssl s_client -connect www.hatena.ne.jp:443
HEAD / HTTP/1.1
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
HTTP/1.1 000 Reason
1xx
2xx
3xx
4xx
5xx
Content-Type: text/html
Content-Type: application/JSON
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Content-Encoding: gzip
gzip
compress
deflate
identity
br
+---+ | Length (24) | +---+---+---+ | Type (8) | Flags (8) | +-+---+---+---+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0!!") !!" +---+
0x0
+---+ |Pad Length? (8)| +---+---+ | Data (*) !!" +---+ | Padding (*) !!" +---+END_STREAM 0x1 PADDED 0x8
0x1
+---+ |Pad Length? (8)|
+-+---+---+ |E| Stream Dependency? (31) | +-+---+---+ | Weight? (8) |
+-+---+---+ | Header Block Fragment (*) !!" +---+ | Padding (*) !!" +---+
:method
:authority
:scheme
:path
:authority :method GET :method POST :path / :path /index.html :scheme http :scheme https :status 200
https:!"api.github.com/repos/hatena/example/
issues/1
POST
GET
PUT PATCH
DELETE
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
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
}
}
}
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;
}
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) {} }
CreateEntity
GetEntity
UpdateEntity
DeleteEntity
ListEntities
CallFunction
CreateFunction
GetFunction
UpdateFunction
DeleteFunction
ListFunctions
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; }
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() }