The Persevere Server persisted data can be accessed and manipulated with a simple and intuitive JSON REST interface. You can store, retrieve, and modify persisted data using standard REST semantics with the following HTTP methods. Clients communicate through these standard HTTP methods. Note - data is transmitted by default in the application/javascript format, allowing things like dates and functions (not included in the JSON spec) to be transmitted nicely. If you're looking for just JSON, add an HTTTP Accept header with a value of application/json. Dates and functions will be serialized in this case. GETThe GET method can be used to retrieve an object by id, a value by path, or a result set by JSONQuery. To retrieve an object by id, simply use the url corresponding to the object. For example to retrieve the /Customer/1 object: GET /Customer/1 To retrieve a value, simply use property path access appended to a starting id. For example: GET /Customer/1.firstName You can use more complex paths: GET /BlogPost/1.comments[0] You can also use JSONQuery queries to retrieve query result sets from the server: GET /Customer/[?firstName='John'] You may use the HTTP Range header to specify a range of items to retrieve. This is recommended for paging through results. Persevere supports a range unit "items" which identifies the items to be retrieved by index. For example one one could use the following request to retrieve the first twenty items of the Customer/ table: GET /Customer/ HTTP/1.1Other range values could include: Range: items=10-19 # items 10 through 19 Persevere will return a Content-Range header indicating the items returned, and the total number of items in the collection.You can use a media type parameter collection in the Accept header to indicate that the collections returned by queries be returned as an object with a specified property holding the collection as an array, rather than the array being the root of the response. In this case, the object will include a property totalCount that will indicate the total number of items. The value of the collection parameter will indicate which property holds the collection array. For example:
POSTYou can use the HTTP POST method to create new items in the table. For example: POST /Customer/ This will add a new customer to the list of customers. If successful, the server will return the newly created object with the newly assigned id: {"id":"4444",
The location of the new resource (corresponding to the assigned id) is available in the PUTYou can modify an existing object by using PUT method to put a new set of values to existing object id. For example we could modify Customer/1 with this request: PUT /Customer/1 You can also use the PUT method to modify individual property values by using path references. For example we could just change the lastName property of the Customer/1 by using the following request: PUT /Customer/1.lastName If the PUT was not successful, the HTTP status code will indicate the failure DELETEYou can delete existing objects by using the DELETE method with the URL for the object. For example we can delete the /Customer/1 object by this request: DELETE /Customer/1 You can also delete a single property by path. For example we could remove the comment property: DELETE /BlogPost/1.comment If the DELETE was not successful, the HTTP status code will indicate the failure Object URL DeterminationThe URL for an object can be determined from the id property by using the standard rules for relative urls. For example if we request: http://mydomain.com/Customer/ We can determine the URL for the first object from id property (which has a value "1") in combination with the context of the requested URL (http://mydomain.com/Customer/). The inferred URL would therefore be http://mydomain.com/Customer/1. ReferencingPersevere supports JSON Referencing which can be used to describe complex data structures and for referencing other objects in the Persevere database or even cross-site references. If an object is lazy loaded, circularly referenced, multiply referenced, or on a foreign site, Persevere will use a reference to the object. References are defined as an object with a property "$ref" with a value that represents the id or path of the target object. References follow the same rules as ids for relative URL inference and path resolution. Therefore a reference to an object that has not been transferred in the current response could be denoted: GET /Customer/1 This denotes that the address property should have a value of the object with the id of Customer/1 (using relative URL inference). A client could do a GET on /Customer/1 to retrieve this object. Circular reference are also described using references: {"id":"1",
References can also have paths in them, which are used by default to reference arrays: {"id":"1",
References can be made to absolute URLs as well: {"id":"1",
Sequencing ControlHTTP is a non-deterministic protocol in regards to ordering when multiple TCP/IP connections (as browsers usually do). If you want to ensure that you requests are sequentially processed in the correct order, you should include an Seq-Id header with each request. For each request, the header value should be incremented one. It is recommended that you use this header in conjunction with the Client-Id header which indicates which page the request is made from. The Client-Id should be randonly generated string. For example: Client-Id: 35523532This would indicate that the request should be processed after the request with a sequence id of 2 and before the request with a sequence id of 4 for the client with the given id. TransactionsTo indicate transactional processing, the Transaction header is used. If the Transaction header is omitted it is always assumed that the modifications made by the current will be committed. If you want the current modification to be included in a transaction set, and you do not want the transaction to be committed until a later request, you should set the Transaction header to "open" like: Transaction: openIt is highly recommended that you use the Transaction header in conjunction with the Seq-Id and Client-Id headers for deterministic ordering so that the commit takes place after the correct modification. Data Integrity/Optimistic LockingWith Persevere you can make conditional requests in order to assert the data state assumptions prior to modifying data. This can be used to provide simple optimistic locking, preventing inadvertent modification of the wrong version of an object. Or it can be used for more sophisticated assertions based on knowledge of the current state of various objects. To make a conditional request, you put a JSONQuery expression in an If header. If the expression in the If header evaluates to false, the request will be rejected with a 412 status code. For example: PUT /Customer/1 HTTP/1.1This PUT would be rejected if the version property does not equal 3. Live Data - Comet SupportPersevere supports Comet style connections for live data updates and for reverse RPC calls (from the server to the client). Persevere supports two forms of Comet communication. The recommended communication is through REST Channels (also known as HTTP Channels). To use the REST Channels, you connect to the Channels servlet (/channels by default), providing a connection id with the Create-Client-Id header. The response will be of the content type "application/http" or "application/rest+json" (clients can use the Accept header to define which format is preferred). If the messages are in JSON format (application/rest+json), they will follow the form:
Persevere also supports Bayeux.
When using Bayeux, subscription requests will be treated by resource subscriptions where the channel
indicates the resource. Publishing messages through Bayeux to an object is functionally equivalent to executing the
SMD Support
You may get an Service Mapping Description (SMD) of the available data sources from the SMD servlet
(which is /SMD by default). The SMD can be used for auto-configuration of services. Cross-Site Data AccessJSONPPersevere can provide access to the persisted data to other websites through JSONP. Authentication for cross-site requests is verified against the Referer header. If a user has authenticated against one website, another website will not be able to automatically use authentication to gain access to the user's data. This prevents cross-site request forgery (CSRF) attacks. Cross-site requests must be properly authenticated on their own in order to gain access to protected resources. To request an object from another site, include a "callback" parameter with the value indicating the name of the callback function to call with the data. In many situations, it may be necessary to transmit and receive additional meta data which would otherwise be sent in HTTP headers. JSONP doesn't support headers. However, you can supply this header/metadata information using the JSONP metadata proposal. XDomainRequest and Cross-Site XHRPersevere also supports IE8's XDomainRequest and W3C Cross-Site Access Control. Requests can be made from other sites, and Persevere will apply the proper headers for use with these mechanisms. Persevere's security system still protects against CSRF with these modes of access. Content Negotiation
Persevere supports content negotiation. Currently, Persevere supports JSON (pure JSON),
JavaScript (basically JSON, but also allows functions). Other format handlers can be defined with custom MIME type handlers and alternate content types can also be uploaded as alternate MIME types for persisted objects. Bulk UpdateObject creation (POST) and object updates (PUT) can be done in bulk. Both POST and PUT requests may have an array of objects, and the request should be sent to table URL. POSTing an array of objects will result in the creation of multiple objects, and PUTing an array of objects will result in the update of multiple objects. When doing a bulk PUT, each object must have it's id property set to the appropriate id. For example: PUT /MyTable/ |