Design Considerations

If you have gotten this far in the book, then you should have a firm understanding of how the Panl server is configured and how to understand, use and implement the Panl response JSON object.  This chapter dives deeper into the considerations that drove the design of the Panl server so that should you wish to peruse the source code you will have a good functioning knowledge of how (and more importantly why) it all fits together.

Notes: At this point in the book, you should be comfortable with the features and functionality of the Panl server


This chapter can be skipped without losing any information, this is the background around the design thinking and consequently the implementation of the codebase.


Through writing this book and describing the features and functionality, it led to more of a focus on the way in which the end user would consume a search site and how developers would integrate and implement the Panl server, rather than any particular architectural purity.


"End user ease and developer implementation and integration was at the forefront of the design, at the small expense of architecture and response payload"


Both the code and the response payload have some interesting design choices. For example, on the code side, in the CollectionReponseHandler implementation, the constructor is passed in the Panl collection URL path, which it definitely does not need to know about.  However, this provides information to better explain the results in the Panl results explainer, additionally, startup messages now are collection context aware.

On the response payload side, when implementing the Panl Results Viewer a new JSON object was added to the active JSON object of sort_fields allowing the developer to know which sort fields are active and the sort order for the field.  This information is contained within the sort JSON array on the active JSON object, however, being able to use a simple lookup, rather than iterating through an array was faster and easier to implement.  Yes, the response payload increases slightly, but the ease of developer integration increases a lot more.

The One-Liner for the Panl server:


Panl was designed to convert Solr faceted search URLs to human readable/SEO friendlier URLs.

(And be as helpful as possible as it does it)


Additionally, during the development, the implementation, startup, and running of the Panl Server, it was designed to be as helpful as possible to ensure that results are returned for any search query (even if a human hand alters the URL path).

Finally the decision was taken to build into the Panl Server some niceties which helps with the development and debugging process, which, of course can be turned off in production mode.

Notes: See the section on 'Panl Configuration' for a complete list of Panl Server options and their implications.

Collections And FieldSet URL Paths (CaFUPs)

The design consideration of the collections and FieldSet is to allow having multiple views over the same returned search data.

Notes: For brevity of documentation, the Collections and FieldSet URL Paths are known as CaFUPs.


A Panl collection is a many-to-one mapping to a Solr collection.  Within each of the defined Panl collection URLs, one or more subset of the returned fields can be returned, these are known as FieldSets.

Each Panl collection must have at least one FieldSet, and can have as many FieldSets as desired.

This was designed so that URLs could be set up which returned just the fields that are required to be displayed on a specific page - rather than retrieving all of the fields.

For example, the if you served up wanted the following URLs

  • /products-by-brands/Caran+d'Ache/b/ which would list all of the models that the brand Caran d'Ache has, and you could then return only a subset of the fields - say the link to an image with a description of the manufacturer.
  • You may also have a specific page for the individual pencil, which may include all of the fields with the total amount of data.
  • Should you implement a search lookahead, you may want to have a very small subset of the FieldSets.

It was also a very deliberate design decision to hide the CaFUPs URL from the front end user.  The front end caller must know of the collection and FieldSet the request corresponds to, and proxy it through to the Panl server.

In-Built Panl Results Testing URLs

The design consideration for this was to have a way to view and test the Panl implementation as it was being developed, however it has uses beyond this for testing and showcasing the results that are returned by the Panl server. Note: that the implementation that was used was based on very rudimentary JavaScript plugins and there are much better ways to implement the search page.

This results viewer simple web app is available on the URL path /panl-results-viewer/ from there the collections and FieldSets can be viewed, along with all searching/faceting functionality.  

It lists all of the available CaFUPs that are available, and it provides all search, faceting, sorting, and pagination available to any Panl web app.

The results explainer simple web app is available on the /panl-results-explainer/ URL path which will show the Panl configuration and additional explanations for the given URL path.

The single search page interface web app is available on the /panl-single-page-search/ URL path that shows a search interface with all of the configured facets.  This includes a search button which will take the user through to the search results for the collection.

All of these in-built results web apps can be disabled with the following property in the panl.properties file.

panl.results.testing.urls=false

Notes: The footer of all of the in-built Panl web-apps notes:

This page is designed to showcase the Panl LPSE encoding mechanism, with

minimal implementation. It is NOT a showcase of web technologies :)

Panl Server Startup

The design consideration was to ensure that during both development and production, Panl will attempt to ensure that it is set up properly, outputting helpful messages where it cannot start, or something is configured which may not be ideal.

On startup, the panl.properties file and any linked <panl_collection_url>.panl.properties files are parsed for correctness, logging information will be output.

INFO log messages are for information only, detailing how the Panl Server has been configured.

Panl does not produce a large amount of logging as it is a type of proxy service to the Solr server, however the underlying technologies that Panl utilises may produce more verbose logging.

WARN log messages mean that Panl has had to alter the way in which the configuration works - this should be fixed before a production deployment.  A helpful message on what to change will be printed.

IMPORTANT: You should fix any WARN logging errors before rolling out any production implementation, as this means that Panl is doing something implicitly, rather than explicitly.


ERROR
log messages will cause the Panl Server to fail to start and will exit with a (hopefully) instructive message on what needs to be fixed.

IMPORTANT:If Panl cannot parse, interpret, or decode the properties, it will throw a PanlServerException and exit.

Error Messaging

The design consideration for handling errors that occur either in Panl or the Solr server was to provide helpful messaging to troubleshoot the problem.  In the case of a 404 status, the links that are available, for a 500 status code, what went wrong in the underlying call.  This may lead to information leakage in a production environment, so both of these messages can be turned down to provide the simplest of responses (which do not provide much help).

404 - Not Found

Any non-mapped URLs will return a HTTP status code of 404 - NOT FOUND, with a list of valid collections that the Panl Server will listen to.  For the exercises in this book, it will return a JSON body response along the lines of:

01

02

03

04

05

06

07

08

{

  "error":true,

  "status": 404,

  "message":"Could not find a PANL request url, see 'valid_urls' array.",

  "valid_urls":[

    "/mechanical-pencils/*"

  ]

}


Which can be seen on the URL
http://localhost:8181/.

Additionally, if you were to use the valid URLs above, the 404 error message would be

01

02

03

04

05

06

07

08

09

10

{

  "error":true,

  "status":404,

  "message":"Could not find a PANL request url, see 'valid_urls' array.",

  "valid_urls": [

    "/mechanical-pencils/default/",

    "/mechanical-pencils/firstfive/",

    "/mechanical-pencils/brandandname/"

  ]

}

Which can be seen at the URL http://localhost:8181/mechanical-pencils/.  

This verbose messaging can be turned off with the property in the panl.properties file:

panl.status.404.verbose=false

If this property is set to false, the following JSON message body will be returned:

01

02

03

04

05

{

  "error":true,

  "status": 404,

  "message":"Not found"

}


500 - Internal Server Error

By default the error message will include the exception message that the Solr server returned.  It is long, URL encoded, but useful for debugging.

The below message states that Invalid Number: 1aa35 for field length, which means that Solr was not able to parse the 1aa35 as a number.  Additionally Panl has not been set up to ensure that the valid values are passed through to Solr.  If Panl field validation is active, Panl would have picked up the incorrect value, parsed it and forwarded the correct value through to the Solr server.

01

02

03

04

05

{

  "error":true,

  "status": 500,

  "message":"Could not query the Solr instance, message was: Error from server at
http://localhost:8983/solr/mechanical-pencils_shard1_replica_n4/select?q=*%3A*&fl=br
and%2Cname%2Ccategory%2Cmechanism_type%2Cnib_shape&facet.mincount=1&rows=10&facet.fi
eld=lead_size_indicator&facet.field=grip_material&facet.field=
colours&facet.field=ni
b_shape&facet.field=
diameter&facet.field=cap_shape&facet.field=brand&facet.field=mec
hanism_type&facet.field=
length&facet.field=hardness_indicator&facet.field=grip_type&
facet.field=cap_material&facet.field=lead_grade_indicator&facet.field=tubing_materia
l&facet.field=in_built_sharpener&facet.field=disassemble&facet.field=category&facet.
field=body_shape&facet.field=clip_material&facet.field=mechanism_material&facet.
fiel
d=lead_length&facet.field=body_material&facet.field=in_built_eraser&facet.field=grip
_shape&facet.field=relative_weight&facet.field=
name&facet.field=nib_material&facet.f
ield=weight&facet.field=variants&facet=true&fq=length%3A%221aa35%22&q.op=AND&_stateV
er_=mechanical-pencils%3A5&wt=javabin&version=2: Invalid Number: 1aa35 for field
length"

}


This verbose messaging can be turned off with the property in the
panl.properties file:

panl.status.500.verbose=false

Which will then return the following message:

01

02

03

04

05

{

  "error":true,

  "status": 500,

  "message":"Internal server error"

}

Testing vs. Production

The design consideration was to have the default mode for the Panl server to be in testing mode with helpful output and messages, and be able to easily turn off the testing configuration.

The default configuration that is included in the Panl Server distribution and the properties that are generated by the Panl Server Generator all include niceties which you may wish to turn off for a production installation.  The properties are as follows:

panl.results.viewer.url=false
panl.status.404.verbose=false
panl.status.500.verbose=false

Quick Middleware

The design consideration was to have the Panl server startup in the shortest amount of time, with minimal dependencies and a subset of functionality.

Allowing a quick start up time, with only configuration through properties file allows for small changes to be made with quick, iterative testing.  This also led to not implementing any authentication, or security in the Panl server.

There is a use case where you would want a user to be able to only search their subset of search results, however the complexity of passing through a unique user ID which was not open to attack or alteration as a facet to the results was not deemed to be a priority.

~ ~ ~ * ~ ~ ~