PrizmDoc v13.4 - Updated
Handle Specific Routes with PAS
Developer Guide > PrizmDoc Application Services > Handle Specific Routes with PAS

How to handle specific routes from PrizmDoc Application Services using custom logic

Application Services is designed to handle all viewer requests in an appropriate way. However, there might be some cases where you need to be able to add custom logic in place of those handlers. Here, we will look at how the request rerouting is done in general, as well as some examples where handling routes in a custom way might be desirable.

Rerouting any request to Application Services

In the API References, every route has a Routes key defined. This is the key that allows handling this route using outside logic. It can be used to instruct Application Services to forward that particular route to any HTTP endpoint that it can access. This is done through the configuration file. Assuming the standard install location, this file would be C:\Prizm\pas\pcc.win.yml, and on Linux, this would be /usr/share/prizm/pas/pcc.nix.yml.

To reroute any route, you will need to know that route's key. In these examples, we will use RouteKey as that key. If you want to simply handle a route, you can use the following config:

routeHandlers.RouteKey.url: "http://myserver/some/route"

You can also define any header you would like used when the request is proxied. This can be useful when wanting to secure a specific route from outside users while still allowing Application Services to use it. This can be configured as such:

routeHandlers.RouteKey.url: "http://myserver/some/route"
# define any header you would like
routeHandlers.RouteKey.headers.x-my-custom-secret: "c2hoLCBJJ20gYSBzZWNyZXQ="
routeHandlers.RouteKey.headers.x-use-any-name: "YW55IG5hbWUsIHJlYWxseQ=="

Application Services will proxy any request to RouteKey to the url specified in the config. Since Application Services routes will sometimes include important information -- such as document ids, markup ids, etc. -- the entire route from Application Services will be appended to the url, as such:

// route as handled by PAS
http://localhost:3000/RouteKey/u1234/sOmEiDvAlUe

// it will be forwarded here, as per the above config
http://myserver/some/route/RouteKey/u1234/sOmEiDvAlUe

If you would prefer to defer handling of that request back to Application Services, you can return a 202 Accepted response to instruct Application Services to continue handling that request as it would normally. Any other response that is returned by the handler will be forwarded back to the client.

Note that since this rerouting is based on an HTTP REST API, the example code that shows how to handle the requests in the following examples will be provided in pseudo-code. It is appropriate to implement this code in any language you feel comfortable using, as long as it can be exposed through an HTTP interface.

Example: How to handle markup file delete permissions

The routes to delete any markup files in Application Services are open to all users, since the Application Services service does not know about system users. However, you can let Application Services know about user access. In the configuration, you will want to handle the following routes as such:

routeHandlers.DeleteMarkupLayer.url: "http://myserver/user/deletepermission"
routeHandlers.DeleteFormDefinition.url: "http://myserver/user/deletepermission"

You could potentially register this route handler on your server:

DELETE http://myserver/user/deletepermission/{markupType}/{markupId}

Using the following pseudo-code, you could determine whether the user is allowed to complete this delete action and instruct Application Services on how to continue:

var markupType = parsedRouteParameters.markupType; // "FormDefinitions" or "MarkupLayers"
var markupId = parsedRouteParameters.markupId; // a guid value

if (userCanDelete(markupType, markupId)) {
    sendResponseStatus(202); // Accepted
    // This will tell Application Services to continue with the delete operation
} else {
    sendResponseStatus(403); // Forbidden
    // The 403 response will be returned to the client
}

Example: How to handle creating sessions

Sometimes, you may not be able to give Application Services access to your documents directly -- for example, when documents are in a custom content management system -- and may want to handle creating sessions on your own. In this example, we will look at handling the legacy CreateSession route.

The following would be an example of the configuration:

routeHandlers.LegacyCreateSession.url: "http://myserver/documents"

You would register a handler, as such, on your server:

GET http://myserver/documents/CreateSession

You would be able to use the following pseudo-code to to handle this request:

var document = parsedQueryParameters.document;
// also make sure to handle the case for the "form" query parsedQueryParameters
// when using the e-sign viewers

var documentData = getDocumentData(document);

// use the ViewingSession API to create the actual session
var sessionResponse = makeRequest({
   method: "POST",
   url: "http://localhost:3000/ViewingSession"
   body: {
       source: {
           type: "upload",
           displayName: documentData.displayName,
           markupId: documentData.uniqueIdentifier
       }
   }
});

// optionally do this later or in a separate thread, for better performance
var uploadResponse = makeRequest({
    method: "PUT",
    url: "http://localhost:3000/ViewingSession/" + sessionResponse.viewingSessionId + "/SourceFile",
    headers: {
        "Accusoft-Secret": "mysecretkey"
    },
    body: documentData.theDocument
});

// return the response back to PAS, to be forwarded to the client
returnResponse(sessionResponse);