I'm trying to deploy some ApexClass from Apex to Production Org using multipart/forma-data to /services/data/v48.0/metadata/deployRequest
following docs.
In the documentation is this example:
POST /services/data/v48.0/metadata/deployRequest
Authorization: Bearer 00D....
Content-Type: multipart/form-data; boundary=--------------------------BOUNDARY
----------------------------BOUNDARY
Content-Disposition: form-data; name="json"
Content-Type: application/json
{
"deployOptions" :
{
"allowMissingFiles" : false,
"autoUpdatePackage" : false,
"checkOnly" : false,
"ignoreWarnings" : false,
"performRetrieve" : false,
"purgeOnDelete" : false,
"rollbackOnError" : false,
"runTests" : null,
"singlePackage" : true,
"testLevel" : "RunAllTestsInOrg"
}
}
----------------------------BOUNDARY
Content-Disposition: form-data; name="file"; filename="deploy.zip"
Content-Type: application/zip
//Contents of deploy.zip
----------------------------BOUNDARY--
The error
"message": "Cannot include more than one non-binary part",
"errorCode": "INVALID_MULTIPART_REQUEST"
So I tried to do it from localhost (using Insomnia) and got the same error.
My steps
1. create deployment package, zip and encode with base64:
src2/
├── classes
│ ├── SomeClass.cls
│ └── SomeClass.cls-meta.xml
└── package.xml
zip -r deploy.zip src2/
cat deploy.zip | base64
UEsDBAoAAAAAAGJRcVEAAAAAAAAAAAAAAAAFABwAc3JjMi9VVAkAA6eTs1+xk7NfdXgLAAEE6AMAAAToAwAAUEsDBBQAAAAIADNRcVF7BrKTnwAAAOYAAAAQABwAc3JjMi9wYWNrYWdlLnhtbFVUCQADUZOzX1OTs191eAsAAQToAwAABOgDAABNjssKwjAQRff5ipC9mShFiqQpIrgW1A8Y21GLzYMmSP17Sx/orOYMhztXl71t+Zu62HhXiLVUgpOrfN24RyGul+MqF6Vh+oTVCx/EB9vFQjxTCjuA6DHIePddRbLyFjZKbUFlYClhjQmFYXwYnT6B4rSPbMnehpfm7C0dWoxRw3L6SQ4tmX2gfjZGnvLgL1DP5U2WS6VhIaZh7mwY+wJQSwMECgAAAAAAK1FxUQAAAAAAAAAAAAAAAA0AHABzcmMyL2NsYXNzZXMvVVQJAANCk7NfQpOzX3V4CwABBOgDAAAE6AMAAFBLAwQUAAAACAAjUXFROpR6ORoAAAAcAAAAGgAcAHNyYzIvY2xhc3Nlcy9Tb21lQ2xhc3MuY2xzVVQJAAMyk7NfWZOzX3V4CwABBOgDAAAE6AMAACsoTcrJTFZIzkksLlYIzs9NdQazqrm4arkAUEsDBBQAAAAIAAdRcVGjd2CHiAAAAK4AAAAjABwAc3JjMi9jbGFzc2VzL1NvbWVDbGFzcy5jbHMtbWV0YS54bWxVVAkAA/2Ss19nk7NfdXgLAAEE6AMAAAToAwAATY1BCsIwEEX3OUXI3kyUIippShE8gbof0qiBNgmdsfT4Firi373Pg2ebeejlFEaKOdVqq42SIfncxfSs1e162RxU44RtS5jPPRLJxU9UqxdzOQFQxqLpkUcftM8D7IzZg6lgCIwdMion5DKLJd7XiKuO2lj4O1aDGPlNrvUcp2Dhi8LCL+3EB1BLAQIeAwoAAAAAAGJRcVEAAAAAAAAAAAAAAAAFABgAAAAAAAAAEADtQQAAAABzcmMyL1VUBQADp5OzX3V4CwABBOgDAAAE6AMAAFBLAQIeAxQAAAAIADNRcVF7BrKTnwAAAOYAAAAQABgAAAAAAAEAAACkgT8AAABzcmMyL3BhY2thZ2UueG1sVVQFAANRk7NfdXgLAAEE6AMAAAToAwAAUEsBAh4DCgAAAAAAK1FxUQAAAAAAAAAAAAAAAA0AGAAAAAAAAAAQAO1BKAEAAHNyYzIvY2xhc3Nlcy9VVAUAA0KTs191eAsAAQToAwAABOgDAABQSwECHgMUAAAACAAjUXFROpR6ORoAAAAcAAAAGgAYAAAAAAABAAAApIFvAQAAc3JjMi9jbGFzc2VzL1NvbWVDbGFzcy5jbHNVVAUAAzKTs191eAsAAQToAwAABOgDAABQSwECHgMUAAAACAAHUXFRo3dgh4gAAACuAAAAIwAYAAAAAAABAAAApIHdAQAAc3JjMi9jbGFzc2VzL1NvbWVDbGFzcy5jbHMtbWV0YS54bWxVVAUAA/2Ss191eAsAAQToAwAABOgDAABQSwUGAAAAAAUABQC9AQAAwgIAAAAA
2. Set two values in header:
Authorization -> Bearer ****
Content-Type -> multipart/form-data; boundary=--------------------------BOUNDARY
3. Set body:
----------------------------BOUNDARY
Content-Type: application/json
Content-Disposition: form-data; name="json"
{
"deployOptions" :
{
"allowMissingFiles" : false,
"autoUpdatePackage" : false,
"checkOnly" : false,
"ignoreWarnings" : false,
"performRetrieve" : false,
"purgeOnDelete" : false,
"rollbackOnError" : false,
"runTests" : null,
"singlePackage" : true,
"testLevel" : "RunAllTestsInOrg"
}
}
----------------------------BOUNDARY
Content-Type: application/zip
Content-Disposition: form-data; name="file"; filename"deploy.zip"
UEsDBAoAAAAAAGJRcVEAAAAAAAAAAAAAAAAFABwAc3JjMi9VVAkAA6eTs1+xk7NfdXgLAAEE6AMAAAToAwAAUEsDBBQAAAAIADNRcVF7BrKTnwAAAOYAAAAQABwAc3JjMi9wYWNrYWdlLnhtbFVUCQADUZOzX1OTs191eAsAAQToAwAABOgDAABNjssKwjAQRff5ipC9mShFiqQpIrgW1A8Y21GLzYMmSP17Sx/orOYMhztXl71t+Zu62HhXiLVUgpOrfN24RyGul+MqF6Vh+oTVCx/EB9vFQjxTCjuA6DHIePddRbLyFjZKbUFlYClhjQmFYXwYnT6B4rSPbMnehpfm7C0dWoxRw3L6SQ4tmX2gfjZGnvLgL1DP5U2WS6VhIaZh7mwY+wJQSwMECgAAAAAAK1FxUQAAAAAAAAAAAAAAAA0AHABzcmMyL2NsYXNzZXMvVVQJAANCk7NfQpOzX3V4CwABBOgDAAAE6AMAAFBLAwQUAAAACAAjUXFROpR6ORoAAAAcAAAAGgAcAHNyYzIvY2xhc3Nlcy9Tb21lQ2xhc3MuY2xzVVQJAAMyk7NfWZOzX3V4CwABBOgDAAAE6AMAACsoTcrJTFZIzkksLlYIzs9NdQazqrm4arkAUEsDBBQAAAAIAAdRcVGjd2CHiAAAAK4AAAAjABwAc3JjMi9jbGFzc2VzL1NvbWVDbGFzcy5jbHMtbWV0YS54bWxVVAkAA/2Ss19nk7NfdXgLAAEE6AMAAAToAwAATY1BCsIwEEX3OUXI3kyUIippShE8gbof0qiBNgmdsfT4Firi373Pg2ebeejlFEaKOdVqq42SIfncxfSs1e162RxU44RtS5jPPRLJxU9UqxdzOQFQxqLpkUcftM8D7IzZg6lgCIwdMion5DKLJd7XiKuO2lj4O1aDGPlNrvUcp2Dhi8LCL+3EB1BLAQIeAwoAAAAAAGJRcVEAAAAAAAAAAAAAAAAFABgAAAAAAAAAEADtQQAAAABzcmMyL1VUBQADp5OzX3V4CwABBOgDAAAE6AMAAFBLAQIeAxQAAAAIADNRcVF7BrKTnwAAAOYAAAAQABgAAAAAAAEAAACkgT8AAABzcmMyL3BhY2thZ2UueG1sVVQFAANRk7NfdXgLAAEE6AMAAAToAwAAUEsBAh4DCgAAAAAAK1FxUQAAAAAAAAAAAAAAAA0AGAAAAAAAAAAQAO1BKAEAAHNyYzIvY2xhc3Nlcy9VVAUAA0KTs191eAsAAQToAwAABOgDAABQSwECHgMUAAAACAAjUXFROpR6ORoAAAAcAAAAGgAYAAAAAAABAAAApIFvAQAAc3JjMi9jbGFzc2VzL1NvbWVDbGFzcy5jbHNVVAUAAzKTs191eAsAAQToAwAABOgDAABQSwECHgMUAAAACAAHUXFRo3dgh4gAAACuAAAAIwAYAAAAAAABAAAApIHdAQAAc3JjMi9jbGFzc2VzL1NvbWVDbGFzcy5jbHMtbWV0YS54bWxVVAUAA/2Ss191eAsAAQToAwAABOgDAABQSwUGAAAAAAUABQC9AQAAwgIAAAAA
----------------------------BOUNDARY--
Question
What am I doing wrong? Is there simpler approach to deploy some classes (which doesn't change) to Prod from Apex? The solution should be lightweight, without using some heavy apex library.
Thanks!