1

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!

1
  • if I answered your question, please consider marking it as an answer – ytiq Nov 21 '20 at 8:37
0

I would suggest use SFDX CLI. It has sfdx force:mdapi:deploy, you don't need to zip package folder, only to pass path to it and login to the org.

4
  • Hi, I can't accept this answer, my requirement is to deploy using Apex. Thanks. – ondrakr Nov 23 '20 at 22:53
  • Why would you deploy your classes from APEX, Apex is not supposed to be used for Prod deployments – ytiq Nov 24 '20 at 16:22
  • I'm working on a managed package, which needs two simple classes to live outside the package (to be without the namespace). This deployment should simplify the package configuration. Right now I achieved my goal with apex-mdapi project by FinancialForce.com, which is SOAP based, but it's a unnecessary heavy approach for such simple task. Another option is to deploy using Tooling API into a sandbox, then these classes can be deployed to production with whatever method, but this is one step more than it could be. – ondrakr Nov 24 '20 at 18:50
  • Well, I'm pretty sure if you only use classes in apex-mdapi you can strip it down to about 200-300 lines, but it would take some time) Cannot come up with better option now( Regarding error, have you tried removing empty lines in your request? – ytiq Nov 24 '20 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.