Можно ли делать выражения / вычисления в JSON?

Я использую замечательный json-сервер в качестве бэкэнда моего приложения, и он действительно полезен для создания пользовательских конечных точек для получения некоторых данных. но что было бы супер полезно, если бы это позволило мне делать вычисления / выражения, чтобы я мог имитировать это поведение бэкэнда тоже.

взять эту структуру данных, например

{
  "products": [
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "false",
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    }
  ]
}

Я хотел бы как-то сказать "discountPrice": couponApplied ? price * couponDiscount

это только у меня псевдокодирование. но я хотел бы сделать кое-что, где я могу вычислить цену на лету. или когда я делаю запрос, он выполняет вычисление и возвращает мне вычисленные данные (как это делает бэкэнд-приложение)

Я понимаю, что могу сделать запрос, применить купон и предоставить эту новую цену. или даже сделать запрос на почту и изменить цену. но это все сделано на стороне клиента. Есть ли способ сделать это либо с помощью JSON или JSON-сервера или любых других решений. если это имеет смысл?

5 ответов

JSON означает JavaScript Object Notation и является структурой данных, и не имеет никакого препроцессора для этого. Вы можете использовать любой анализатор JSON и динамически добавлять нужные значения.

Итак, вкратце: нет, нет возможности добавлять динамические значения

Нет, вы не сможете выполнять вычисления внутри json. Данные должны быть видоизменены в другом месте, а затем отправлены.

Нет, в JSON невозможно выполнить математику или любое другое выражение, поскольку JSON - это просто формат структуры данных, а не язык программирования.

Вам нужно будет загрузить данные JSON, используя выбранный вами язык программирования, после чего вы сможете манипулировать ими.

Например, поскольку вы упоминаете javascript в качестве примера простую программу Node.

//It would be better to use the FileSystem API, but for simplicity for this example, I'm using require
var json = require('./myjson.json'); 
var product = json.products[0];

//Since the dataset has "false", this if will handle both "false" (string) and false (boolean) values. The value should really be boolean if possible
product.discountPrice = product.couponApplied && product.couponApplied !== "false" ? product.price * couponDiscount : null;

Если вы пытаетесь создать логику динамически, например, пользователь создает некоторую логику, и вы хотите сохранить ее в БД, а затем применить где-нибудь, это может быть полезно:

В вашем примере использование синтаксического анализатора формул может выглядеть так:

const response = {
  "products": [
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "false",
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    },
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "true",
      "couponDiscount": 0.2,
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    }
  ],
  formulaFields: {
    "discountPrice": 'IF("{couponApplied}"="true", {price} * {couponDiscount}, "")', // excel standard formula, with {variable} as product field keys
  }
}

const productsWithValues = response.products.map((product)=>{
  const productWithValues = { ...product };
  for (const field in response.formulaFields){
    const formula = response.formulaFields[field].replace(/\{([^\}]+)\}/g, (_, key) => product[key])
    const parser = new Parser();
    const { result } = parser.parse(formula);
    productWithValues[field] = result;
  }
  return productWithValues;
})
console.log(productsWithValues)

Выход:

[
  {
    "name": "football",
    "id": "SPO-001",
    "category": "sport",
    "price": 40,
    "couponApplied": "false",
    "coupons": ["daw124qdw", "a1212cxn"],
    "discountPrice": null
  },
  {
    "name": "football",
    "id": "SPO-001",
    "category": "sport",
    "price": 40,
    "couponApplied": "true",
    "couponDiscount": 0.2,
    "coupons": ["daw124qdw", "a1212cxn"],
    "discountPrice": 8
  }
]

Обратите внимание, что json-server позволяют добавлять пользовательское промежуточное ПО. Таким образом, вы можете написать что-то вроде этого:

const updateProduct = (p) => ({
  ...p,
  discountPrice: p.couponApplied ? p.price * p.couponDiscount : p.price
})

const transform = ({products, ...rest}) => ({
  ...rest, 
  products: products.map(updateProduct)
})

const modify = (req, res, next) => {
  if (req.path !== '/my-route') return next();

  res.body = JSON.stringify(transform(JSON.parse(res.body)))
  next();
}


// dummy call -- would really be handled by json-server/express

(() => {
  const req = {path: '/my-route'};
  const res = {body: `{"products":[{"name":"football","id":"SPO-001","category":"sport","price":40,"couponApplied":false,"coupons":["daw124qdw","a1212cxn"]},{"name":"helmet","id":"SPO-042","category":"sport","price":50,"couponApplied":true,"couponDiscount":0.75,"coupons":["foobarbaz"]}]}`}
  const next = () => {console.log(JSON.parse(res.body))}
  
  modify(req, res, next)
})()

JSON не поддерживает это, но если вы превратите его в объект Javascript, вы можете сделать что-то вроде этого:

var obj = JSON.parse(
`{
  "products": [
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "true",
      "couponDiscount": 0.5,
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    }
  ]
}`).products[0];

Object.defineProperty(obj,"discountPrice",{
  get:function(){
    return (this.couponApplied==="true"||this.couponApplied===true) ? this.price*this.couponDiscount : this.price;
  },
  set:function(){
    return;
  }
});

console.log(obj.discountPrice);

При этом используется дескриптор метода доступа для определения свойства объекта, которое зависит от значений других свойств объекта.

Другие вопросы по тегам