vibe-d / vibe.d

Official vibe.d development
MIT License
1.15k stars 284 forks source link

Getting and sending JSON correctly #2725

Open AlexanderZhirov opened 1 year ago

AlexanderZhirov commented 1 year ago

How to properly receive JSON and send it, given that I do it this way?

auto jsr = req.json;

string number = jsr["number"].get!string;
string transport = jsr["transport"].get!string;
string password = jsr["password"].get!string;
string context = jsr["context"].get!string;
string max_contacts = jsr["max_contacts"].get!string;

How to read the array that is inside? It is not possible to lead to the desired type, writes errors.

auto allows = jsr["allows"].get!array;
500 - Internal Server Error

Internal Server Error

Internal error information:
std.json.JSONException@std/json.d(1808): Got JSON of type undefined, expected string.
----------------
../../.dub/packages/vibe-d-0.9.6/vibe-d/data/vibe/data/json.d:1218 const pure @safe void vibe.data.json.Json.checkType!(immutable(char)[]).checkType(immutable(char)[]) [0x55e4fe4075e4]
../../.dub/packages/vibe-d-0.9.6/vibe-d/data/vibe/data/json.d:653 inout pure @property @trusted inout(immutable(char)[]) vibe.data.json.Json.get!(immutable(char)[]).get() [0x55e4fe4074c7]
source/app.d:294 void app.write(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) [0x55e4fe3f276c]
source/app.d:107 void app.postReq(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) [0x55e4fe3f0ca2]
/usr/include/dlang/dmd/std/functional.d-mixin-1677:1688 void function(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) std.functional.DelegateFaker!(void function(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)*).DelegateFaker.doIt [0x55e4fe3fff97]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/router.d:274 @trusted void vibe.http.router.URLRouter.handlerDelegate!(void delegate(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)).handlerDelegate(void delegate(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse)).__lambda3!(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse).__lambda3(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) [0x55e4fe403980]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/router.d:218 @safe bool vibe.http.router.URLRouter.handleRequest(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse).__lambda6!(ulong, immutable(char)[][]).__lambda6(ulong, scope immutable(char)[][]) [0x55e4fe5064ee]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/router.d:734 const @safe bool vibe.http.router.MatchTree!(vibe.http.router.Route).MatchTree.doMatch(immutable(char)[], scope bool delegate(ulong, scope immutable(char)[][]) @safe) [0x55e4fe508e30]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/router.d:667 @safe bool vibe.http.router.MatchTree!(vibe.http.router.Route).MatchTree.match(immutable(char)[], scope bool delegate(ulong, scope immutable(char)[][]) @safe) [0x55e4fe508653]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/router.d:211 @safe void vibe.http.router.URLRouter.handleRequest(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) [0x55e4fe506160]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/server.d:2304 @safe bool vibe.http.server.handleRequest(vibe.internal.interfaceproxy.InterfaceProxy!(vibe.core.stream.Stream).InterfaceProxy, vibe.core.net.TCPConnection, vibe.http.server.HTTPServerContext, ref vibe.http.server.HTTPServerSettings, ref bool, scope stdx.allocator.IAllocator) [0x55e4fe5abe98]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/server.d:253 @trusted void vibe.http.server.handleHTTPConnection(vibe.core.net.TCPConnection, vibe.http.server.HTTPServerContext).__lambda14() [0x55e4fe5aa263]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/server.d:245 @safe void vibe.http.server.handleHTTPConnection(vibe.core.net.TCPConnection, vibe.http.server.HTTPServerContext) [0x55e4fe5a9e60]
../../.dub/packages/vibe-d-0.9.6/vibe-d/http/vibe/http/server.d:2042 nothrow @safe void vibe.http.server.listenHTTPPlain(vibe.http.server.HTTPServerSettings, void delegate(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) @safe).doListen(vibe.http.server.HTTPServerContext, bool, bool, bool).__lambda6(vibe.core.net.TCPConnection) [0x55e4fe513cca]
../../.dub/packages/vibe-core-2.2.0/vibe-core/source/vibe/core/task.d:737 nothrow void vibe.core.task.TaskFuncInfo.set!(void delegate(vibe.core.net.TCPConnection) nothrow @safe, vibe.core.net.TCPConnection).set(ref void delegate(vibe.core.net.TCPConnection) nothrow @safe, ref vibe.core.net.TCPConnection).callDelegate(ref vibe.core.task.TaskFuncInfo) [0x55e4fe6e619c]
../../.dub/packages/vibe-core-2.2.0/vibe-core/source/vibe/core/task.d:758 void vibe.core.task.TaskFuncInfo.call() [0x55e4fe6b9eb1]
../../.dub/packages/vibe-core-2.2.0/vibe-core/source/vibe/core/task.d:457 nothrow void vibe.core.task.TaskFiber.run() [0x55e4fe6b909e]
??:? void core.thread.context.Callable.opCall() [0x55e4fe748524]
??:? fiber_entryPoint [0x55e4fe7a7a63]

There are no examples in the documentation of how to get an array in the desired format.

auto allows = jsr["allows"].get!Json[];
../../.dub/packages/vibe-d-0.9.6/vibe-d/data/vibe/data/json.d(1124,8): Error: static assert:  "Unsupported JSON type 'Json'. Only bool, long, std.bigint.BigInt, double, string, Json[] and Json[string] are allowed."
../../.dub/packages/vibe-d-0.9.6/vibe-d/data/vibe/data/json.d(1200,36):        instantiated from here: `typeId!(Json)`
../../.dub/packages/vibe-d-0.9.6/vibe-d/data/vibe/data/json.d(653,4):        instantiated from here: `checkType!(Json)`
source/app.d(294,32):        instantiated from here: `get!(Json)`
/usr/bin/dmd failed with exit code 1.

Are there any clearer examples about converting a large number of variables to Json? Without using prepared structures.

s-ludwig commented 1 year ago

auto allows = jsr["allows"].get!array;

auto allows = jsr["allows"].get!Json[];

This should be jsr["allows"].get!(Json[]) - and .get!(Json[string]) for reading JSON objects. It's missing the parenthesis, so that the [] applies to the return value of get() instead of being part of the requested type.

In general, you can serialize any D type to JSON using vibe.data.json.serializeToJson (or serializeToPrettyJson). Some types may need to be adjusted using custom toJson and fromJson methods to get a usable result, but most types work as-is. Similarly, if the JSON format is fixed, deserializeJson would be the quick way to parse JSON back into