The is no getting around it. CardDAV is complicated. CardDAV is confusing. But CardDAV is not impossible. I know. I built a CardDAV client for CloudSponge to power our integrations for iCloud, AOL and others.
Building a CardDAV client does take some tenacity because there are very few readable resources out there. You end up reading the RFC many times over until the ideas take shape and it becomes possible to implement. Either that or it puts you to sleep and you try again tomorrow.
Tired of reading CardDAV RFCs? We can help. Our Contacts API abstracts the hard stuff.
So what are the hardest parts about CardDAV? In this article, I’m going to address one of the more complicated challenges: Reading multiple contacts at once.
Get the VCards in a single request
As long as you have a list of the VCard URIs, you can request many of them at once using the REPORT method and the addressbook-multiget
payload.
There’s an HTTP verb for this: REPORT. CardDAV calls this an addressbook-multiget
request. Inside this request, you’ll send an array of all the URIs you want to retrieve as href
s.
I’ll assume that you already have your VCard URIs and show you an example of such a request and response.
With a request like:
REPORT /home/username/contacts/ <c:addressbook-multiget xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> <d:prop> <--- tell the server which properties you want... <d:getetag /> <c:address-data> <c:allprop /> <--- I want all the address book data </c:address-data> </d:prop> <d:href>/home/username/contacts/vcard001.vcf</d:href> <d:href>/home/username/contacts/vcard002.vcf</d:href> </c:addressbook-multiget>
You may get a response like:
HTTP/1.1 207 Multi-Status <?xml version="1.0" encoding="utf-8" ?> <d:multistatus xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/home/username/contacts/vcard001.vcf</d:href> <d:propstat> <d:prop> <d:getetag>"dd49fe-7a1265"</D:getetag> <c:address-data>BEGIN:VCARD VERSION:4.0 NICKNAME:Admiral Ackbar FN:Gial Ackbar EMAIL:gialackbar@example.com END:VCARD </c:address-data> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/home/username/contacts/vcard002.vcf</d:href> <d:status>HTTP/1.1 404 Resource not found</d:status> </d:response> </d:multistatus>
Notice, I’ve bolded a few lines to draw attention to them. Firstly, the response code is an unusual 207
which indicates that the overall request was successful, but that individual responses should be inspected.
The payload contains an array of response nodes. Each one contains its own status. I’ve highlighted the two responses in the sample payload. The first is a friendly 200. The second, a 404.
This is the trick with the multiget request: each requested entity has its own status.
Now that you’ve retrieved the VCards, you can inspect each one that has a successful response and pull out the VCard from the address-data
node.
Here’s where you’ll find the addressbook-multiget description and some examples in RFC6352.
Tired of reading CardDAV RFCs? We can help. Our Contacts API abstracts the hard stuff.