Torbjørn
Torbjørn

Reputation: 6503

How to convert object to json in Nim

I'm making a small web service in Nim, and I need to respond to requests with json. I'm using the jester module to make the service. I expect I can use the json module in Nim's base library to construct some kind of object with fields and values, and then convert it to a json string. But how? Or is there a better way to construct json in Nim?

Upvotes: 14

Views: 5034

Answers (4)

dom96
dom96

Reputation: 1022

For anyone else finding the marshal-based answer in this thread. Use this instead:

import json

type
  Person = object
    age: int
    name: string

var p = Person(age: 38, name: "Torbjørn")
echo(%p)

Note that you should not be using marshal for this purpose, it is the equivalent of the pickle module in Python and it may generate JSON that has extra data that you likely don't want. Also, right now it's just a coincidence that it generates JSON, it may choose a different format in the future.

Upvotes: 8

zachaysan
zachaysan

Reputation: 1826

Do the following:

import json

var jsonResponse = %*
                   {"data": [{ "id": 35,
                               "type": "car",
                               "attributes": {"color":"red"} }]}

var body = ""

toUgly(body, jsonResponse)

echo body

Upvotes: 2

Grzegorz Adam Hankiewicz
Grzegorz Adam Hankiewicz

Reputation: 7681

In Nim you use the json module to create JsonNode objects which are object variants. These can be constructed with the individual procs like newJObject() and then populate the fields sequence. Another quicker way is to use the %() proc which accepts a sequence of tuples where one value is the string with the json field and the other the individual JsonNode.

Here's an example showing both ways:

import json

type
  Person = object ## Our generic person record.
    age: int ## The age of the person.
    name: string ## The name of the person.

proc `%`(p: Person): JsonNode =
  ## Quick wrapper around the generic JObject constructor.
  result = %[("age", %p.age), ("name", %p.name)]

proc myCustomJson(p: Person): JsonNode =
  ## Custom method where we replicate manual construction.
  result = newJObject()
  # Initialize empty sequence with expected field tuples.
  var s: seq[tuple[key: string, val: JsonNode]] = @[]
  # Add the integer field tuple to the sequence of values.
  s.add(("age", newJInt(p.age)))
  # Add the string field tuple to the sequence of values.
  s.add(("name", newJString(p.name)))
  result.fields = s

proc test() =
  # Tests making some jsons.
  var p: Person
  p.age = 24
  p.name = "Minah"
  echo(%p) # { "age": 24,  "name": "Minah"}
  p.age = 33
  p.name = "Sojin"
  echo(%p) # { "age": 33,  "name": "Sojin"}
  p.age = 40
  p.name = "Britney"
  echo p.myCustomJson # { "age": 40,  "name": "Britney"}

when isMainModule: test()

Upvotes: 12

zah
zah

Reputation: 5384

The marshal module includes a generic object-to-json serialisation algorithm that works for any type (currently, it uses run-time type introspection).

import marshal

type
  Person = object
    age: int
    name: string

var p = Person(age: 38, name: "Torbjørn")

echo($$p)

The output will be:

{"age": 38, "name": "Torbj\u00F8rn"}

Upvotes: 29

Related Questions