gorilla/mux framework (rk-boot): RPC error code design

introduce

This article introduces how to design reasonable API error codes under the gorilla/mux framework through a complete example .

We will use rk-boot to start the gorilla/mux microservice .

Please visit the following address for the complete tutorial:

scope of consideration

A reasonable RPC error needs to consider the following aspects.

  • Contains error codes, error messages
  • Error messages are extensible
  • Consider readability
  • Parsability, that is, the user can parse the error code through the code and take effective action
  • Avoid internal error benefits, e.g. Nil point error

Error code structure

{
    "error":{
        "code":500,
        "status":"Internal Server Error",
        "message":"Panic manually!",
        "details":[]
    }
}

Install

go get github.com/rookie-ninja/rk-boot/mux

quick start

With rk-boot , users can easily build gorilla/mux framework microservices. rk-boot integrates Panic capture and standard error types.

complete example

1. Create boot.yaml

The boot.yaml file describes the meta information of the gorilla/mux framework startup, and rk-boot starts gorilla/mux by reading boot.yaml .

---
mux:
  - name: greeter
    port: 8080
    enabled: true

2. Create main.go

Make /v1/greeter return an error.

// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.

package main

import (
	"context"
	"github.com/rookie-ninja/rk-boot"
	"github.com/rookie-ninja/rk-boot/mux"
	"github.com/rookie-ninja/rk-common/error"
	"github.com/rookie-ninja/rk-mux/interceptor"
	"net/http"
)

func main() {
	// Create a new boot instance.
	boot := rkboot.NewBoot()

	// Register handler
	entry := rkbootmux.GetMuxEntry("greeter")
	entry.Router.NewRoute().Methods(http.MethodGet).Path("/v1/greeter").HandlerFunc(Greeter)

	// Bootstrap
	boot.Bootstrap(context.TODO())

	boot.WaitForShutdownSig(context.TODO())
}

func Greeter(writer http.ResponseWriter, request *http.Request) {
	err := rkerror.New(
		rkerror.WithHttpCode(http.StatusAlreadyReported),
		rkerror.WithMessage("Trigger manually!"),
		rkerror.WithDetails("This is detail.", false, -1, 0.1))

	rkmuxinter.WriteJson(writer, http.StatusAlreadyReported, err)
}

3. Start main.go

$ go run main.go

4. Verify

$ curl "localhost:8080/v1/greeter?name=rk-dev"
{
    "error":{
        "code":208,
        "status":"Already Reported",
        "message":"Trigger manually!",
        "details":[
            "This is detail.",
            false,
            -1,
            0.1
        ]
    }
}

Catch Panic (system crash)

We still use the demo code as an example.

In the RPC implementation, we try to crash the system to see how rk-boot automatically captures and returns what information to the user.

1. Modify main.go

// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.

package main

import (
	"context"
	"github.com/rookie-ninja/rk-boot"
	"github.com/rookie-ninja/rk-boot/mux"
	"net/http"
)

func main() {
	// Create a new boot instance.
	boot := rkboot.NewBoot()

	// Register handler
	entry := rkbootmux.GetMuxEntry("greeter")
	entry.Router.NewRoute().Methods(http.MethodGet).Path("/v1/greeter").HandlerFunc(Greeter)

	// Bootstrap
	boot.Bootstrap(context.TODO())

	boot.WaitForShutdownSig(context.TODO())
}

func Greeter(writer http.ResponseWriter, request *http.Request) {
	panic("Panic manually!")
}

2. Verify

$ curl "localhost:8080/v1/greeter?name=rk-dev"
{
    "error":{
        "code":500,
        "status":"Internal Server Error",
        "message":"Panic manually!",
        "details":[]
    }
}

source code

Error handling in rk-boot is implemented in rk-common/error .

more examples

Please refer to: rk-demo for more examples.

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324116393&siteId=291194637