I'll start out with this: I much prefer REST to SOAP. REST has some great advantages, if done right, like distributability, cacheability of responses, clear defined semantics, the ability to be consumed directly in a browser, and so on. However, I like arguing against myself, so here's why you should use SOAP in your next project. A lot of these points come from REST In Practice which everyone should have on his/her desk when starting a REST-y project.
SOAP is everywhere
In the '00s, SOAP replaced a ton of un-interoperable technologies like CORBA, DCOM, RMI, to name a few. If there's a legacy system that you need to integrate with of that vintage, chances are it speaks SOAP, and will happily consume your WSDL. Every language imaginable has a tool that will parse WSDL into domain objects, and loads of developers know how to use it. That can't necessarily be said for REST. You could also go through the pain of interacting with a REST service through an HTTP client library directly (like Apache's HTTP Components). Tool support for REST is getting better: the latest JAX-RS 2.0 has a standard client that's pretty nice to use.
The S in SOAP stands for Simple
Here's the specification for SOAP 1.1. It's short, and outlines quite clearly what a SOAP message looks like. A lot of the spec is dedicated to IMO esoteric cases (never in 10 years have I ever used a partially-transmitted array, e.g.), but the meat of it is: Envelope, Header, Body. I'll concede that the Header and Envelope are redundant when the SOAP message is sent over HTTP, but SOAP can be sent over any medium (as another answer mentions), so it's a necessary evil. You can easily eyeball a SOAP message, and you don't need fancy software to write one either.
WS-* extensions add functionality
There's no in-built transaction support in REST-ful web services. It's possible to make a transactional REST service, but the semantics of your transactional system may be different from the semantics of my transactional system. SOAP has extensions like WS-Transactions that define clear workflows and mechanisms for transactional consistency. Likewise, other extensions like WS-Addressing and WS-Security describe message routing and message authentication/encryption. To do message authentication in REST, you either have to use client-side SSL, or roll your own.
SOAP doesn't require you to map domain operations onto CRUD
REST is not all about CRUD, but to perform non-CRUD operations, you have to map them onto resources. That's not necessarily a bad thing™, but it can cause your designers some headaches. Mapping a verb-operation like "check out a book" to one of the HTTP verbs could be a
PATCH request to set an
isCheckedOut flag on the
book; it could be creating a new
/checkout resource, or any number of other things. With a SOAPy web service, and auto-generated code from WSDL, you might simply do
service.checkOut(book, patron). The intent is very clear.
SOAP's Fault mechanism encourages richer fault handling
OK, so it's not perfect, and most SOAP web services don't do it right, but that's not SOAP's fault. SOAP has built-in support for exceptions (faults), that are actual objects. They can contain great detail about what went wrong, and how you might fix it. REST's use of HTTP status codes is incredibly handy in this regard, because it encourages the developer to think about whether they should send back a 400, 403, 500, etc. and these codes have standard meanings. However, there's no standard for the message body, and there's no REST mechanism to enforce my-crappy-REST-service from sending back
200 OK responses with error bodies. It's just as easy for a REST service to produce unhelpful responses as it is for a SOAP service.
Maybe these aren't great reasons to use SOAP over REST in your next project, but I kind of wanted to try to convince myself.
I'm on a project at the moment that exposes a REST API, and consumes a SOAP API, so I'm in the best/worst of both worlds. I hate the SOAP stuff, but that's mostly because the back-end system that I'm working with leaves room for improvement. JAX-RS is a really nice server-side REST API, and it's nearly painless. Because of REST, and because we're being really strict about sticking to the REST constraints, we're making great use of HTTP caching in our infrastructure which will hopefully improve our user experience. We're not, however, doing a full-on HATEOAS service because our application simply doesn't require it. Our service is also primarily CRUD by its nature, so we haven't needed to make hard decisions about how to noun a verb.
In short, I guess SOAP isn't always a bad choice, but there's not a lot going for it unless you have a big SOAP infrastructure already.