PrizmDoc Viewer v13.21 Release - Updated
Developer Guide / PAS / Handle Specific Routes with PAS
In This Topic
    Handle Specific Routes with PAS
    In This Topic


    This topic covers how to handle specific routes from PAS using custom logic. PAS is designed to handle all viewer requests in an appropriate way. However, there might be some cases where you need 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 PAS

    In the API Reference section, 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 PAS 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:

    • On Windows: C:\Prizm\pas\
    • On Linux: /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 PAS 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=="

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

    // route as handled by PAS
    // it will be forwarded here, as per the above config

    If you would prefer to defer handling of that request back to PAS, 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: 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 PAS are open to all users, since PAS does not know about system users. However, you can let PAS 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 PAS 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 PAS access to your documents directly. For example, when documents are in a custom content management system and you 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 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