Forum Discussion

jeffshurtliff's avatar
5 years ago

Possible to update custom metadata field with API v2 POST call?

Does anyone know if it is possible to update a custom metadata field using the v2 API or is it only possible to do so using the v1 API?

In our environment we have a side nav component that is populated via JSON (i.e. hash) data stored in a custom metadata field in the categories and boards collections.

For example, let's say the v1 metadata name is custom.side_nav and the v2 metadata name is c_side_nav.  I know that I can use LiQL to query for the value of c_side_nav like this:

 

SELECT c_side_nav FROM categories WHERE id = 'some-category'

 

I also know that I can update the metadata value using the v1 API and a URL-encoded query string like this:

 

<#assign postUrl = "/categories/id/${categoryID}/settings/name/custom.side_nav/set" />
<#assign postUrl = postUrl + "?value=${jsonDataString?url}" />
${restadmin(postUrl)}

 

But I've been having some intermittent issues where certain v1 POST calls to certain categories are failing with 413 status codes and the following error:

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">\n<TITLE>ERROR: The request could not be satisfied</TITLE>\n</HEAD><BODY>\n<H1>413 ERROR</H1>\n<H2>The request could not be satisfied.</H2>\n<HR noshade size="1px">\nBad request.\nWe can\'t connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.\n<BR clear="all">\nIf you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.\n<BR clear="all">\n<HR noshade size="1px">\n<PRE>\nGenerated by cloudfront (CloudFront)\nRequest ID: C7A_WoVVjuk3c78VlbY3OROQRsg7wPwdksEBA_hxM-Z9w5plIaltQg==\n</PRE>\n<ADDRESS>\n</ADDRESS>\n</BODY></HTML>

 

So it would be really nice if I could do a more "normal" POST call and pass the JSON string as API payload rather than having to URL encode it, because I feel like that may be why some of my API calls are failing.

🆕Edit: Alternatively, does anyone know if it's possible to perform an API v1 POST call by passing payload rather than using query strings?  Cuz that would also be very useful.

  • You should probably stick with the REST V1 call since we don't currently support setting a node setting in REST V2.

    For REST V1 calls can do a multipart/form-data request and include your parameters as form parameters:

    curl --location --request POST 'http://yourcommuntiy.com/restapi/vc/categories/id/intermingles/settings/name/custom.side_nav/set' \
    --header 'Content-Type: application/json' \
    --header 'Li-Api-Session-Key: JO_JDmgXJ5WI8P_2b2bnBXzSsX5-SHCPneB0qLxYttQ.' \
    --form 'value={ "json": "string" }'

    If you are doing the call in a Freemarker endpoint, you could make a call like the following (it's ok to use a query param b/c the code is executing server-side):

    <#assign settingPostCall = restBuilder()
       .version("v1")
       .method("POST")
       .path("/categories/id/" + categoryId + "/settings/name/custom.side_nav/set")
       .queryParam("value", jsonDataString) />
    <#assign resp = settingPostCall.call() />

     

    I hope that helps!

    -Doug

  • DougS's avatar
    DougS
    Khoros Oracle

    You should probably stick with the REST V1 call since we don't currently support setting a node setting in REST V2.

    For REST V1 calls can do a multipart/form-data request and include your parameters as form parameters:

    curl --location --request POST 'http://yourcommuntiy.com/restapi/vc/categories/id/intermingles/settings/name/custom.side_nav/set' \
    --header 'Content-Type: application/json' \
    --header 'Li-Api-Session-Key: JO_JDmgXJ5WI8P_2b2bnBXzSsX5-SHCPneB0qLxYttQ.' \
    --form 'value={ "json": "string" }'

    If you are doing the call in a Freemarker endpoint, you could make a call like the following (it's ok to use a query param b/c the code is executing server-side):

    <#assign settingPostCall = restBuilder()
       .version("v1")
       .method("POST")
       .path("/categories/id/" + categoryId + "/settings/name/custom.side_nav/set")
       .queryParam("value", jsonDataString) />
    <#assign resp = settingPostCall.call() />

     

    I hope that helps!

    -Doug

    • DougS's avatar
      DougS
      Khoros Oracle

      For the Freemarker case, I just tried it and found a bug with the restBuilder path parsing (filing a bug to fix this in our next release). This call worked for me however (again, it's server-side so the query param should be ok):

      <#assign resp = restadmin("/categories/id/" + categoryId + "/settings/name/custom.side_nav/set?value=" + jsonDataString?url) />

      -Doug

    • Thanks a ton, DougS, this is all super helpful! I really appreciate the suggestions and syntax! And thanks SuzieH for your help as well!