Thư viện chuẩn
JSON
JSON.parse/stringify của Node.js so với encoding/json (Go), serde_json (Rust), Codable (Swift) và Jackson (Java) để map field.
- Phiên bản tối thiểu
- Node.js ≥ 12.20Go ≥ 1.0Rust ≥ 1.71Swift ≥ 5.0Java ≥ 25
- Đã chạy thử trên
- Node.js 24.12.0Go 1.27.1Rust 1.98.1Swift 6.2.4Java 25.0.4.1
Code Node.js là ES module: lưu file .mjs hoặc đặt "type": "module" trong package.json.
JSON.parse/JSON.stringify của Node.js làm việc trực tiếp với object thường, không cần khai báo shape trước. Go cần một struct với tag json:"..." để encoding/json biết map field nào vào key nào — nhưng việc map này được giải quyết lúc runtime qua reflection: key JSON nào không khớp field sẽ bị bỏ qua âm thầm, và chỉ kiểu dữ liệu của field trong struct được kiểm tra lúc biên dịch, chứ không phải việc map tag ↔ key. Rust không có JSON built-in trong std, nên dùng cặp crate serde/serde_json với derive macro #[derive(Serialize, Deserialize)] — việc map field/key được kiểm tra ngay lúc biên dịch qua macro, chặt hơn Go. Swift dùng protocol Codable có sẵn trong ngôn ngữ, cũng được trình biên dịch tự sinh code map field. Java không có JSON trong thư viện chuẩn — JEP 540 (Simple JSON API) mới đang đề xuất thêm nó dưới dạng incubator (jdk.incubator.json) từ JDK 28, còn ở JDK 25 hiện tại thì chưa có gì cả — nên ví dụ dưới dùng thư viện phổ biến nhất, Jackson.
Parse (unmarshal) và stringify (marshal)
let jsonstr = '{"foo":"bar"}'
let parsed = JSON.parse(jsonstr)
console.log(parsed) // { foo: 'bar' }
jsonstr = JSON.stringify(parsed)
console.log(jsonstr) // {"foo":"bar"}package main
import (
"encoding/json"
"fmt"
)
type T struct {
Foo string `json:"foo"`
Bar string `json:"bar,omitempty"` // bỏ qua khi rỗng lúc marshal
}
func main() {
jsonstr := `{"foo":"bar"}`
t := new(T)
if err := json.Unmarshal([]byte(jsonstr), t); err != nil {
panic(err)
}
fmt.Println(t) // &{bar }
marshalled, err := json.Marshal(t)
if err != nil {
panic(err)
}
jsonstr = string(marshalled)
fmt.Println(jsonstr) // {"foo":"bar"}
}// Cargo.toml: serde = { version = "1", features = ["derive"] }
// Cargo.toml: serde_json = "1"
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct T {
foo: String,
#[serde(default, skip_serializing_if = "String::is_empty")] // bỏ qua khi rỗng lúc serialize
bar: String,
}
fn main() {
let jsonstr = r#"{"foo":"bar"}"#;
let t: T = serde_json::from_str(jsonstr).unwrap();
println!("{t:?}"); // T { foo: "bar", bar: "" }
let jsonstr = serde_json::to_string(&t).unwrap();
println!("{jsonstr}"); // {"foo":"bar"}
}import Foundation
struct T: Codable {
var foo: String
var bar: String? // Codable tự sinh dùng encodeIfPresent cho Optional, tự bỏ key khi nil — không cần tự viết encode(to:)
}
let jsonstr = #"{"foo":"bar"}"#
let t = try JSONDecoder().decode(T.self, from: Data(jsonstr.utf8))
print(t) // T(foo: "bar", bar: nil)
let encoded = try JSONEncoder().encode(t)
print(String(decoding: encoded, as: UTF8.self)) // {"foo":"bar"}import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
// Maven: com.fasterxml.jackson.core:jackson-databind:2.22.3
record T(String foo, @JsonInclude(JsonInclude.Include.NON_EMPTY) String bar) {}
void main() throws Exception {
ObjectMapper mapper = new ObjectMapper();
String jsonstr = "{\"foo\":\"bar\"}";
T t = mapper.readValue(jsonstr, T.class);
IO.println(t); // T[foo=bar, bar=null]
jsonstr = mapper.writeValueAsString(t);
IO.println(jsonstr); // {"foo":"bar"}
}Tham khảo: github.com/miguelmota/golang-for-nodejs-developers#json