go-siris / siris

DEPRECATED: The community driven fork of Iris. The fastest web framework for Golang!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Faster Json Renderer

godofdream opened this issue · comments

The default Iris Json renderer uses encode/json.
For fast Json Rendering (and also parsing) there is https://github.com/mailru/easyjson.
We should add an easy option to use easyjson.

Hmm, do you realy think this will be a god choise? It's incompatible to normal json encoder like interfaces loose types... so it would be really only with a option a good idea. Maybe we need to check also others to find a more full supporting JSON encoder/decoder.

Btw https://github.com/json-iterator/go/ would be a better alternative

wow https://github.com/json-iterator/go/ is fast. I didn't knew this project yet.
If we replace the default json encoder I propose to make a configurationflag for it.
This way we don't touch the api.

see https://github.com/go-siris/siris/tree/feature/json-interator

maybe you like to check and test:

package main

import (
	"github.com/go-siris/siris"
	"github.com/go-siris/siris/context"
)

type Company struct {
	City  string        `json:"City"`
	Other string        `json:"Other"`
	Demo  []interface{} `json:"demo"`
	D     struct {
		E1 struct {
			E2 bool  `json:"e2"`
			G  []int `json:"g"`
		}
	}
	Name string `json:"Name"`
}

func MyHandler(ctx context.Context) {
	c := &Company{}
	if err := ctx.ReadJSON(c); err != nil {
		ctx.StatusCode(siris.StatusBadRequest)
		ctx.WriteString(err.Error())
		return
	}

	ctx.JSON(c)
}

func MyHandler2(ctx context.Context) {
	c := &Company{}
	if err := ctx.ReadJSON(c); err != nil {
		ctx.StatusCode(siris.StatusBadRequest)
		ctx.WriteString(err.Error())
		return
	}

	ctx.Writef("Received: %#v\n", c)
}

func main() {
	app := siris.New()

	app.Post("/", MyHandler)

	app.Post("/2", MyHandler2)

	// use Postman or whatever to do a POST request
	// to the http://localhost:8080 with RAW BODY:
	/*
		{
			"Name": "siris-Go",
			"City": "New York",
			"Other": "Something here",
			"demo": ["josef",2,3,true],
			"d": {
				"e1": {
					"e2": true,
					"g": [1,2,3,4]
				}
			}
		}
	*/
	// and Content-Type to application/json
	//
	// The response should be:
	// /:
	// {"City":"New York","Other":"Something here","demo":["josef",2,3,true],"D":{"E1":{"e2":true,"g":[1,2,3,4]}},"Name":"siris-Go"}
	// /2:
	// Received: &main.Company{City:"New York", Other:"Something here", Demo:[]interface {}{"josef", 2, 3, true}, D:struct { E1 struct { E2 bool "json:\"e2\""; G []int "json:\"g\"" } }{E1:struct { E2 bool "json:\"e2\""; G []int "json:\"g\"" }{E2:true, G:[]int{1, 2, 3, 4}}}, Name:"siris-Go"}
	app.Run(siris.Addr(":8080"), siris.WithJSONInteratorReplacement)
}

@Dexus, damn, you're so fast in implementation new things!

Thanks for good example.

@threestarsgenius Thanks. I need some things myself, so I have to do something. But I hope there are others, that contribute good and fast extensions and/or write test, examples and other stuff that may be of interest.

@Dexus btw, what about this issue json-iterator/go#81 ? Seems to be it's not fully compatible.

@threestarsgenius i have seen it, but the maintainer is fast of those reports. give him a bit time, and he will fix it.
Its no clone of encoding/json its a dropin replacement that fits the most needs. To bad that there ist not very good doc...

I will try to fix the compatibility issue as soon as possible.

Thank you @taowen very nice!

json-iterator/go#81 is fixed now. we could switch to the new branch.
I did only POC tests as i don't use the json renderer in any of my projects yet.
Could anyone else approve?

It should be stable enough now.
On one of my API, I use the branch and have no problems with enabled jsoniter.