🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Different results when creating a post in Studio vs. using the HTTP API

14 replies
Last updated: Feb 27, 2021
I am getting different results when I create a new post in Studio, versus when I create the same post via the HTTP API.
The Studio post ends up wrapped inside a “content” object (which is there because of the Tabs plugin), while the API post does not. Why? They should both use the same schema config, right?
Feb 26, 2021, 2:42 PM
Hm, I removed the Object wrapper, and now it works the same in both. But still interesting that it behaved differently.
Feb 26, 2021, 2:56 PM
Hi Johannes. The HTTP API won’t abide by your schema or any validation rules set up in your Studio (see the Gotcha at the top of this page ). If you run a create mutation it will follow the few rules set out here but otherwise, it can be expected to add what you ask for and nothing more.
In your follow-up you said it works the same for you after removing the wrapper. I’m not sure which wrapper you mean but hopefully the behaviour is working predictably for you now.
Feb 26, 2021, 3:17 PM
Thanks, I realize I am running into more complications with this than I first thought.I was under the impression I could define the Schema, and then post an entire document via the API as long as I mapped to the same fields as defined in the schema.

My use case is 90% auto-generated content (retrieved from other APIs), but where the editors should be able to override manually/append.
So I need to create an entire Vehicle record, including references to Brand, as well as Images.

Are there any guides or examples on what that would look like?
Feb 26, 2021, 4:17 PM
or sorry, to ask more precisely:Is it possible to do something like this?


(HTTP POST body)
{ 
  "mutations": [
    { 
      "create": { 
        "_type": "vehicle", 
        "licensePlate": "AB4566774456" ,
        "modelName":"Irizar",
        "modelYear":"2009-04-01",
        "manufacturer":"_1233455-MAN", //this is a reference ID
        "images":[
            {"url":"path to my image", "caption":"caption goes here", "alt":"alt text goes here"},
            {"url":"path to my image", "caption":"caption goes here", "alt":"alt text goes here"},
            {"url":"path to my image", "caption":"caption goes here", "alt":"alt text goes here"}
        ]       
      } 
    }
  ]
}
Feb 26, 2021, 4:23 PM
I was under the impression I could define the Schema, and then post an entire document via the API as long as I mapped to the same fields as defined in the schema.
Yes, I’d agree with this.

Is it possible to do something like this?
I can’t see why not. The one thing you might need to add is a
_key
, but as long as this matches your schema I’d expect it to work.
Feb 26, 2021, 4:29 PM
I just added this to my schema for a document called `author`:

{
  name: "images",
  type: "array",
  of: [
    {
      type: "object",
      name: "imageObj",
      fields: [
        { type: "string", name: "caption" },
        { type: "string", name: "url" },
      ]
    }
  ]
}
Then ran this:


{ 
  "mutations": [
    { 
      "create": { 
        "_type": "author", 
        "name": "A Name",
		"images": [
		  {"url": "<http://www.you.com|www.you.com>", "caption": "Some caption"},
		  {"url": "<http://www.me.com|www.me.com>", "caption": "Some caption"}
		]
      } 
    }
  ]
}
Other than getting a missing
_key
warning in the Studio, it worked. I’m not sure what it would take to resolve a url into an image, but the data is coming in and is well-formed.
Feb 26, 2021, 4:34 PM
I think the tab plugin you're using might have created some confusion here, as it creates that extra layer of depth (the
content
field).
When you're synchronizing data with external systems, you'll usually want to use stable IDs so you can more easily know what the documents in Sanity refers to in other systems.

For instance, if you're importing vehicles, setting a document id to something like
vehicle-someIdFromExternalSystem
will allow you to use operations like
createIfNotExists
and/or
createOrReplace
to ensure you only have one copy of things.
References point to other documents, so that's another reason to create explicit IDs - you can create and reference them within the same transaction. For instance, in your case you could POST a mutation transaction like this:


[
  {
    "createIfNotExists": {
      "_id": "manufacturer-kokos",
      "_type": "manufacturer"
    }
  },
  {
    "patch": {
      "id": "manufacturer-kokos",
      "setIfMissing": {
        "name": "Kokos Inc",
        "founded": 1987
      }
    }
  },
  {
    "createIfNotExists": {
      "_id": "vehicle-chewy",
      "_type": "vehicle",
    }
  },
  {
    "patch": {
      "id": "vehicle-chewy",
      "setIfMissing": {
        "licensePlate": "ABC123",
        "manufacturer": {"_ref": "manufacturer-kokos", "_type": "reference"},
        "bilder": [
          {
            "_type": "image",
            "_key": "someUniqueKey",
            "caption": "Some caption",
            "asset": {"_ref": "image-someImageHash-200x300-png", "_type": "reference"}
          }
        ]
      }
    }
  }
]
We're using
createIfNotExists
+
patch
here so as not to overwrite existing values for the fields that might have been modified by editors, but depending on your use case you could also use two
createOrReplace
operations (one for each document).
If you want to use Sanity for hosting images, you'll need to uploading images first using the assets API, which should return document IDs you can reference as seen above (the
bilder[0].asset
field).
The javascript client makes this stuff a little easier, if that's an option.
Feb 26, 2021, 7:13 PM
(I may have gotten your data structure slightly wrong in these patches, as I'm not familiar with the tab plugin, but hopefully this should be somewhat helpful regardless 🙂 )
Feb 26, 2021, 7:14 PM
Perfect, thats exactly the type of example I was looking for. In my case the vehicle data comes from multiple external sources, so my plan was to use Sanity as the master system of record , thus I was originally happy with the auto-generated ID’s. But good point about using excplicit IDs - I see how that allows me to create/update/insert in the same transaction 👍. Thanks both, very helpful.
Feb 26, 2021, 8:10 PM
How do I add an image to an array, and not just a singleton image field?I have tried several variants, but keep getting errors:
Variant 1: using
type:reference

{
       "patch": {
       "id": "vehicle-kj34348",
       "insert": {
            "after": "bilder[-1]",
            "items": [
                {"_key":"128438djodjkljkje", "_ref": "image-388d64edc205296b4d6853eb1b2bd2bf168205b9-2500x2500-svg", "_type": "reference"}
            ]
      }
Feb 26, 2021, 10:53 PM
variant 2, using type:image.This adds an image record to the array, but no asset.

{
       "patch": {
       "id": "vehicle-kj34348",
       "insert": {
            "after": "bilder[-1]",
            "items": [
                {"_key":"key123443", "_ref": "image-388d64edc205296b4d6853eb1b2bd2bf168205b9-2500x2500-svg", "_type": "image"}
            ]
      }

Feb 26, 2021, 10:56 PM
So the "image" type has this shape:
{
  "_type": "image",
  "caption": "Some caption",
  "asset": {"_ref": "image-someImageHash-200x300-png", "_type": "reference"}
}
Eg, the reference is nested inside the
asset
property. So I think you want:
{
  "patch": {
  "id": "vehicle-kj34348",
  "insert": {
    "after": "bilder[-1]",
    "items": [
      {
        "_type": "image",
        "_key": "key123443",
        "asset": {
          "_type": "reference",
          "_ref": "image-388d64edc205296b4d6853eb1b2bd2bf168205b9-2500x2500-svg"
        },
        "caption": "Optionally, some caption"
      }
    ]
  }
}
Feb 26, 2021, 11:33 PM
Perfect, that was it! Really appreciate all the help 👍
Feb 27, 2021, 9:40 AM
The mutation API is one of my favorite parts of Sanity, always happy to explain 🙂
Feb 27, 2021, 7:01 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?