rest icon indicating copy to clipboard operation
rest copied to clipboard

Support for recursive schemas

Open juicyarts opened this issue 1 year ago • 0 comments

Hey folks. Some weeks ago i started using a-h/rest but faced the limitation that circular/recursive structures were not really parseable due to an endless loop of RegisterModel which ends up in a stackoverflow.

=== RUN   TestSchema/recursive-models.yaml
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0x14021130390 stack=[0x14021130000, 0x14041130000]
fatal error: stack overflow

runtime stack:
runtime.throw({0x1031941c0?, 0x0?})
	/opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/panic.go:1023 +0x40 fp=0x172176d50 sp=0x172176d20 pc=0x102d40420
runtime.newstack()
	/opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/stack.go:1103 +0x460 fp=0x172176f00 sp=0x172176d50 pc=0x102d5dd60
runtime.morestack()
	/opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/asm_arm64.s:341 +0x70 fp=0x172176f00 sp=0x172176f00 pc=0x102d7ab40

goroutine 30499 gp=0x14000312540 m=11 mp=0x14000250908 [running]:
reflect.resolveNameOff(0x1032fdc20?, 0x15f09?)
	/opt/homebrew/Cellar/go/1.22.1/libexec/src/runtime/runtime1.go:610 +0x38 fp=0x14021130390 sp=0x14021130390 pc=0x102d78038
reflect.(*rtype).nameOff(...)
	/opt/homebrew/Cellar/go/1.22.1/libexec/src/reflect/type.go:533
reflect.(*rtype).PkgPath(0x0?)
	/opt/homebrew/Cellar/go/1.22.1/libexec/src/reflect/type.go:665 +0xa4 fp=0x140211303b0 sp=0x14021130390 pc=0x102ddb174
github.com/a-h/rest.(*API).getModelName(0x1400085d2c0, {0x103377688, 0x1032fdc20})
	/Users/huess/repos/heimspiel/tools/rest/schema.go:172 +0x34 fp=0x14021130460 sp=0x140211303b0 pc=0x103183434
github.com/a-h/rest.(*API).RegisterModel(0x1400085d2c0, {{0x103377688?, 0x1032fdc20?}, 0x0?}, {0x14021130e08, 0x1, 0x0?})
	/Users/huess/repos/heimspiel/tools/rest/schema.go:264 +0x48 fp=0x14021130b40 sp=0x14021130460 pc=0x1031838f8

kin-openapi provided an update with better circular reference handling in the meantime, but the loop is caused by the implementation in a-h/rest and not within kin-openapi.

We really like the abstraction of a-h/rest and would love to use it for our use case which unfortunately has heavy usage of deeply nested recursive structs. To support this use case i extended the behavior a bit and would like to know if you would like to adopt this, before i open a pr..

See https://github.com/a-h/rest/compare/main...heimspiel:rest:cd4495c641787636aae807deaecee0baf8b4085d

This implementation works well with the latest kin-openapi version (0.126), the former one will throw an error like this

failed to resolve, due to external references: kin-openapi bug found: circular schema reference not handled with length ...

juicyarts avatar Jul 10 '24 13:07 juicyarts