The goal of caching is to increase performance. This is done in several ways:
- Client caching can prevent the need for some network requests.
- Reverse cache proxies can respond to requests without the origin servers and databases needing to respond.
- Servers can be allowed to tell clients that their cache is still valid, decreasing the number of network requests.
The central point is to enable more work to be done without having to make a costly request to the server. The more requests that the reverse cache proxies can respond to, the faster the application runs and the more it can scale. Everyone benefits from caching.
An ETag is an opaque identifier assigned by a web server to a specific version of a resource found at a URL. If the resource content at that URL ever changes, a new and different ETag is assigned. Used in this manner ETags are similar to fingerprints, and they can be quickly compared to determine if two versions of a resource are the same or not. Comparing ETags only makes sense with respect to one URL; ETags for resources obtained from different URLs may or may not be equal, so no meaning can be inferred from their comparison.Wikipedia
The FamilySearch API provides ETags on Persons, Relationships, Change History, Discussions, and Sources. The ETags are weak, meaning that resources with matching ETags are semantically equivalent, but not byte-for-byte identical. In other words, the data is the same but might be in a different order.
While ETags are a replacement for version numbers, they are not sequential. That is, a comparison can determine only whether two resources are the same; a comparison cannot determine which revision is most recent.
To check the current version of a resource without being sent the actual resource in the response, you can do a
and check the ETag that is returned.
HEAD requests return the same headers that would be returned in a
HTTP/1.1 200 OK Last-Modified: Thu, 24 Jan 2013 21:59:56 GMT ETag: W/"a7bd095f6058737fc90e709453352acc74903a0b" Content-Type: application/xml Cache-Control: no-transform, max-age=3600 Content-Location: /platform/tree/persons/KWQY-DCB
You can also perform a conditional GET by specifying the If-None-Match header.
A conditional GET means the resource is returned only if the ETag in the
If-None-Match header does not match the current version. When
the specified ETag does match the current version, a 304 Not Modified is
GET /platform/tree/persons/KWQY-DCB If-None-Match: W/"a7bd095f6058737fc90e709453352acc74903a0b"
HTTP/1.1 304 Not Modified Last-Modified: Thu, 24 Jan 2013 21:59:56 GMT ETag: W/"a7bd095f6058737fc90e709453352acc74903a0b" Content-Type: application/xml Cache-Control: no-transform, max-age=3600 Content-Location: /platform/tree/persons/KWQY-DCB
Conditional GETs prevent the need to perform a
HEAD request to check for a new version and then performing a
GET request to get
the new version when available.
You can also perform a conditional POST by specifying the If-Match and If-Unmodified-Since headers.
A conditional POST means the resource is updated only if the ETag in the
If-Match header matches the current version. If
the current version does not match the value of the ETag as specified in the
If-Match header, a 412 Precondition Failed is
POST /platform/tree/persons/KWQY-DCB If-Unmodified-Since: Thu Jan 14 15:40:24 MST 2016 If-Match: J8Y5VFR <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <gedcomx xmlns="http://gedcomx.org/v1/" xmlns:fs="http://familysearch.org/v1/" xmlns:atom="http://www.w3.org/2005/Atom"> <person id="12345"> <fact type="http://gedcomx.org/Birth" id="ABCDE"> <attribution> <changeMessage>...change message...</changeMessage> </attribution> <date> <original>3 Apr 1836</original> </date> <place> <original>Moscow, Russia</original> <normalized xml:lang="en">Moscow, Moskva, Russia</normalized> </place> </fact> </person> </gedcomx>
HTTP/1.1 412 Precondition Failed Transfer-encoding: chunked Cache-control: no-cache, no-store, no-transform, must-revalidate, max-age=0 Vary: Accept-Encoding Vary: Accept, Accept-Language, Accept-Encoding, Expect Date: Thu, 14 Jan 2016 22:40:24 GMT Warning: 400 FamilySearch "Unable to check preconditions.: java.text.ParseException: Error parsing entity tag: Error parsing entity tag" X-processing-time: 1 Content-location: /platform/tree/persons/12345
No Batch Endpoints
Caching is the reason the FamilySearch API does not offer a batch person endpoint. Requests to batch endpoints are not cacheable. Because
URIs are used as the key, responses to
persons?id=3,2,1 are stored separately even though they
are semantically equivalent. By allowing for persons to be requested only one at a time, we maximize the cache efficiency, which in turn decreases
the load on our servers and allows the system to run faster.
Caching is also the reason we recommend using the Authorization header to
authenticate requests. If you use the
access_token query parameter, then resources can be cached only for that session (since the cache
is keyed by the URL). This is why the following warning header is applied to the response when you use the
access_token query parameter:
Warning: 199 FamilySearch Best Practice Violation: Authorization header should be used instead of using the access_token query parameter.
Note In order to avoid CORS preflight requests, we acknowledge that the query parameter may need to be used.
Cached data may cause security problems. If an authorized user reads data into cache and the cache is not purged at the end of that user’s session, it may still be available to the next unauthorized user. For this reason, you should not store cached data in local memory, and you should purge cached data at the end of each user session and if the browser back button is used.