Skip to content

Instantly share code, notes, and snippets.

@neuralsandwich
Last active November 11, 2018 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neuralsandwich/e65f710d647a590932b5256441ea2316 to your computer and use it in GitHub Desktop.
Save neuralsandwich/e65f710d647a590932b5256441ea2316 to your computer and use it in GitHub Desktop.
Hello World
$ curl -d '{"s": "Hello, World!"}' http://localhost:8080/count
{"c":13}
$ curl -d '{"s": "Hello, World!"}' http://localhost:8080/uppercase
{"s": "HELLO, WORLD!"}
package main
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
)
var ErrEmptyString = errors.New("empty string")
type stringRequest struct {
S string `json:"s"`
}
type countResponse struct {
C int `json:"c"`
}
type uppercaseResponse struct {
S string `json:"s"`
}
func count(s string) int {
return len(s)
}
func uppercase(s string) string {
return strings.ToUpper(s)
}
func countHandler(w http.ResponseWriter, r *http.Request) {
var request stringRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
fmt.Println(err)
}
if request.S == "" {
json.NewEncoder(w).Encode(ErrEmptyString)
}
response := &countResponse{
C: count(request.S),
}
json.NewEncoder(w).Encode(response)
}
func uppercaseHandler(w http.ResponseWriter, r *http.Request) {
var request stringRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
fmt.Println(err)
}
if request.S == "" {
json.NewEncoder(w).Encode(ErrEmptyString)
}
response := &uppercaseResponse{
S: uppercase(request.S),
}
json.NewEncoder(w).Encode(response)
}
func main() {
http.HandleFunc("/count", countHandler)
http.HandleFunc("/uppercase", uppercaseHandler)
http.ListenAndServe(":8080", nil)
}
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
package main
import (
"fmt"
"net/http"
)
func helloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World")
}
func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8080", nil)
}
// for each method, we define request and response structs
type uppercaserequest struct {
s string `json:"s"`
}
type uppercaseresponse struct {
v string `json:"v"`
err string `json:"err,omitempty"` // errors don't define json marshaling
}
type countrequest struct {
s string `json:"s"`
}
type countresponse struct {
v int `json:"v"`
}
// for each method, we define request and response structs
type uppercaserequest struct {
s string `json:"s"`
}
type uppercaseresponse struct {
v string `json:"v"`
err string `json:"err,omitempty"` // errors don't define json marshaling
}
type countrequest struct {
s string `json:"s"`
}
type countresponse struct {
v int `json:"v"`
}
// Endpoints are a primary abstraction in go-kit. An endpoint represents a single RPC (method in our service interface)
func makeUppercaseEndpoint(svc StringService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
v, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{v, err.Error()}, nil
}
return uppercaseResponse{v, ""}, nil
}
}
func makeCountEndpoint(svc StringService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
v := svc.Count(req.S)
return countResponse{v}, nil
}
}
type StringService interface {
Uppercase(string) (string, error)
Count(string) int
}
package main
import (
"errors"
"strings"
)
type StringService interface {
Uppercase(string) (string, error)
Count(string) int
}
// stringService is a concrete implementation of StringService
type stringService struct{}
func (stringService) Uppercase(s string) (string, error) {
if s == "" {
return "", ErrEmpty
}
return strings.ToUpper(s), nil
}
func (stringService) Count(s string) int {
return len(s)
}
// ErrEmpty is returned when an input string is empty.
var ErrEmpty = errors.New("empty string")
// Transports expose the service to the network. In this first example we utilize JSON over HTTP.
func main() {
svc := stringService{}
uppercaseHandler := httptransport.NewServer(
makeUppercaseEndpoint(svc),
decodeUppercaseRequest,
encodeResponse,
)
countHandler := httptransport.NewServer(
makeCountEndpoint(svc),
decodeCountRequest,
encodeResponse,
)
http.Handle("/uppercase", uppercaseHandler)
http.Handle("/count", countHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request uppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
func decodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request countRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
$ curl -d '{"s": "Hello, World!"}' http://localhost:8080/count
{"v":13}
$ curl -d '{"s": "Hello, World!"}' http://localhost:8080/uppercase
{"v": "HELLO, WORLD!"}
package main
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Peter Bourgon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import (
"context"
"encoding/json"
"errors"
"log"
"net/http"
"strings"
"github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
)
// StringService provides operations on strings.
type StringService interface {
Uppercase(string) (string, error)
Count(string) int
}
// stringService is a concrete implementation of StringService
type stringService struct{}
func (stringService) Uppercase(s string) (string, error) {
if s == "" {
return "", ErrEmpty
}
return strings.ToUpper(s), nil
}
func (stringService) Count(s string) int {
return len(s)
}
// ErrEmpty is returned when an input string is empty.
var ErrEmpty = errors.New("empty string")
// For each method, we define request and response structs
type uppercaseRequest struct {
S string `json:"s"`
}
type uppercaseResponse struct {
V string `json:"v"`
Err string `json:"err,omitempty"` // errors don't define JSON marshaling
}
type countRequest struct {
S string `json:"s"`
}
type countResponse struct {
V int `json:"v"`
}
// Endpoints are a primary abstraction in go-kit. An endpoint represents a single RPC (method in our service interface)
func makeUppercaseEndpoint(svc StringService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(uppercaseRequest)
v, err := svc.Uppercase(req.S)
if err != nil {
return uppercaseResponse{v, err.Error()}, nil
}
return uppercaseResponse{v, ""}, nil
}
}
func makeCountEndpoint(svc StringService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) {
req := request.(countRequest)
v := svc.Count(req.S)
return countResponse{v}, nil
}
}
// Transports expose the service to the network. In this first example we utilize JSON over HTTP.
func main() {
svc := stringService{}
uppercaseHandler := httptransport.NewServer(
makeUppercaseEndpoint(svc),
decodeUppercaseRequest,
encodeResponse,
)
countHandler := httptransport.NewServer(
makeCountEndpoint(svc),
decodeCountRequest,
encodeResponse,
)
http.Handle("/uppercase", uppercaseHandler)
http.Handle("/count", countHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request uppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
func decodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request countRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment