Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
trailpack-proxy-router
Advanced tools
The Proxy Engine Router is an Express middleware built to be used on Trailsjs with Proxy Engine. It's purpose is to allow for easy development, SEO, and AAA (Triple A - Automated Analytical Assessment) testing from the ground up (a concept developed by Scott Wyatt). This means that you can automate UI testing and can still use your own controllers to handle views and add Proxy Route content to them as needed.
Views are stored in either a Flat File database or joined with a Postgres database, and are cache-able in a document store such as Redis. Each view has a series of tests that are displayed based on a weight, threshold, and baseline for a given demographic.
Each time a view is run, the engine will determine which series to display and track the runs for a given view and positive/negative control conversions for the demographic to score it. Once a Series threshold and baseline is met, it becomes the default view for a given demographic.
To read why this is important, checkout out our article on AAA Testing
Say good bye to A/B testing as AAA testing can handle hundreds of different series test at once for each view in a web app and it can do it automatically. This makes UI testing purely iterative and personable.
AAA Testing isn't about one size site fits all, it's about finding the right layout per audience. Series documents are given a test number, and version. They default to the latest version, but the default can be changed to any version while keeping the run and score.
Large changes to any version should be given another test number. The documents are markdown documents with yaml that allow you to use normal markdown, HTML, or even your own embeds.
Use your own mechanisms to track negative and positive interactions and then feed them back to Proxy Engine to adjust the score.
Use your own mechanisms to determine what qualifies as a demographic.
One of the most difficult feats when dealing with a CMS, from a developer standpoint, is continuity:
All of these are issues for the Modern Web, especially for web apps built as single page applications.
Proxy Engine's router takes care of these pain points by:
Repo | Build Status (edge) |
---|---|
trailpack-sequelize |
Repo | Build Status (edge) |
---|---|
trailpack-express |
$ npm install --save trailpack-proxy-router
// config/main.js
module.exports = {
packs: [
// ... other trailpacks
require('trailpack-proxy-router')
]
}
// config/web.js
middlewares: {
order: [
... other middleware
'proxyRouter', // proxyRouter must be before router
'router'
],
proxyRouter: function(req, res, next){
return require('trailpack-proxy-router/lib').Middleware.proxyRouter(req, res, next)
}
}
// config/proxyRouter.js
module.exports = {
// The Default Extension to use when creating/updating/reading files, falls back to either .md or .html
default_extension: '.md',
// Default Threshold
threshold: 100,
// Default Baseline
baseline: 0.75,
// Default Weight
weight: 50,
// Default Flat File Folder
folder: 'content',
// Default name for "series"
series: 'series',
// Force Flat File and ignore DB
force_fl: true,
// The number of controls to enqueue before flushing to processor.
flush_at: 20,
// The number of milliseconds to wait before flushing the queue automatically to processor.
flush_after: 10000,
// Cache
cache: {
// The redis datastore prefix
prefix: 'pxy',
// Allow Caching
allow: true,
// Milliseconds before cache is ejected
eject: 10000
}
}
By default the Proxy Route content directory is content
in the root directory of your application. However, it can changed to any directory or even a node_module by setting the folder
value in config/proxyRouter
. Whatever the content folder, the file structure must follow these guidelines:
a0
with a SemVer versioned markdown document.a0
, b0
, c0
etc. Upon exceeding z0
change to a1
, b1
, c1
etc.:world
or *
will match express routes..md
(markdown) or .html
(HTML) file extension, but a test directory must be of all one file type. - content
- hello
- :world
- series
- a0
- 0.0.0.md
- earth
- series
- a0
- 0.0.0.md
- html
- series
- a0
- 0.0.0.html
- 0.0.1.html
- series
- a0
- 0.0.0.md
- series
- a0
- 0.0.0.md
- 0.0.1.md
- b0
- 0.0.0.md
Proxy Route merges the document's id, series, version, and metadata with req.locals so it can be used in any view template engine required.
To access it in your template engine use the request's local variable proxyRouter.document
and proxyRouter.meta
When the trails app starts, two configurations are added to trailsApp.config.proxyRouter:
ignoreRoutes
alternateRoutes
Ignored Routes are any routes that do not use the GET method or have an app config with ignore set to true
// config/routes.js
...
{
method: ['GET'],
path: '/ignore/me',
handler: 'IgnoreController.me',
config: {
app: {
proxyRouter: {
ignore: true
}
}
}
}
It's important to ignore routes that you don't want Proxy Route to check as it will speed up the application.
Alternate Routes are any routes that use the GET method and have a wildcard or an express parameter in the url eg /home/*
or /hello/:world
.
This is useful for when a child route may not have a specific view eg. /products/1
and the wildcard might eg. products/:id
. With this schema, you need not make a view for each product, and instead just define the wildcard templates which the product will inherit. This does allow you to still have extreme control over any individual page while also having a fallback.
By default trailpack-proxy-route has no policies to prevent anything from hitting the RouteController endpoints. You will need to create policies with your authentication strategy to determine what is allowed to hit them. We recommend using Proxy Permissions which makes this easy and will lock down administrative endpoints automatically.
For Proxy Router to work on a server cluster as a Flat File server, Redis is required. After any route or series is updated as a Flat File, an event is produced to all other servers in the cluster to copy the flat files to their folder structure. This is quick, but expect a few milliseconds of lag.
If you are hosting your repository on GitHub, then great news, when you create/update/destroy a Page or Series on a production web app, Proxy Router can issue a pull request to your repo. This keeps your remote Flat Files in sync with your production application.
TODO example
This is the default home page located at /content/series/a0/index.md
---
title: Homepage Hello World
keywords: proxy-engine, amazing
runs: 0
score: 0.0
demographics:
- {name: 'unknown'}
scripts:
- /i/can/do/arrays/too.js
- /path/to/special/page/script.js
og: {'image': '/and/cool/things/like/og-tags.jpg'}
---
<header-component>
</header-component>
# Homepage Hello World
<h2>I can use Normal HTML</h2>
I can even use embeds like a youtube video or my own custom ones.
@[youtube](lJIrF4YjHfQ)
I can even use custom HTML DOM like ones from Angular
<login>
</login>
<footer-component [wow]="amazing">
</footer-component>
*** Note: Html components must end on a newline or else they are wrapped by a paragraph tag. This is part of Common Mark Spec.
Demographics is a generic term because they can literally be anything. For example Let's say we have a site that's homepage needs some simple A/B testing. We have no information about our user, so we can classify them as "Unknown" which is the default demographic. Now, we can set up two series: a0 and b0 and split visits equally with a weight of 50. When our user visits the home page, Proxy Router will send them a0 or b0 and track the view that was run. Now the user does something on the home page which should issue a Positive or Negative control.
When a user does something we don't like on the page, we want to send a negative control back to Proxy Router. For example, if they leave the website, then we might send a negative control. That said, if the user was visiting the a0 series of the homepage, then a0 would get a reduction in it's overall score. If the user does something that we like on the page, for example clicks "Buy Now", then we might want to send a positive control that increases the score of a0. We continue this process until the Baseline and Threshold is met.
Every Page has a baseline. The baseline is the minimal times the page can be viewed before the threshold comes into effect. Imagine it as a survey, where you want 1000 people to take the survey before you review the results. From the previous example between a0 and b0, let's say a 1000 people visit the home page. After that 1000 people have visited, we should have some decent scores from a0 and b0 for example a0 scored 0.89 and b0 score 0.70. Proxy Route now examines the threshold and will predict that a0 is more productive then b0. If we set the threshold to .90, then we will stop testing between a0 and b0 when a0 reaches 0.90 and begin serving only a0 for the "unknown" demographic.
A max series score is 1.0 and a min series score is 0.0. This score is the result of positive/negative scores from some machine learning (nothing too fancy) and user interactions. When a user clicks on let's say a button, we can issue a click event with a score between 1 and 100 based on how important that is too us. For example, a page link maybe get a issue a score of 1, while a "Buy Now" may issue a score of 100. Proxy-engine will take that event score and compare it to the previous score, runs of the series, the threshold of the page, and the weight of series distribution.
TODO Truncate tests that are failing a standard deviation from the mean after the baseline is met.
Markdown-it is used to parse the document from markdown/html to html.
Is used to give the flat file readable meta data as well as give the displayed page meta data.
Is used to give the flat files the ability to use html components typical of angular, angular2 and react
Markdown-it Block Embed Embed is used to grant the parsed document embed-ables. This could be youtube, vimeo, your own short codes, whatever!
An example of using req.proxyroute
. RouteController.view can return a view as html or as JSON.
Builds the Flat File structure to the database
Builds the Database to a Flat File Structure
Adds a Route Model (Page)
Edits a Route Model (Page)
Removes a Route Model (Page)
Adds a RouteDocument Model (Document)
Edits a RouteDocument Model (Document)
Removes a RouteDocument Model (Document)
Adds a Positive or Negative value for a series
Gets a rendered page from a flatfile given the express request object @returns
{
id: String, // The id of the Route Model (in this case the ID is null since it's a flat file)
path: String, // The original request path
series: String, // The Series Test of the Route Document Model
version: String, // The Test Version of the Route Document Model
meta: Object, // The Meta Data from the Route Document Model
document: String // The Rendered HTML of the Route Doucment Model
}
Resolves and Renders a Route Document
Gets a rendered page from the database given the express request object
@returns
{
id: String, // The id of the Route Model
path: String, // The original request path
series: String, // The Series Test of the Route Document Model
version: String, // The Test Version of the Route Document Model
meta: Object, // The Meta Data from the Route Document Model
document: String // The Rendered HTML of the Route Doucment Model
}
Adds a run score to a series
Adds a positive score to a series
Adds a negative score to a series
Adds a Page (Route Model).
Calls RouteService.createPage()
Adds a Page (Route Model)
Edits a Page (Route Model).
Calls RouteService.updatePage()
Updates a Page (Route Model)
Removes a Page (Route Model).
Calls RouteService.destroyPage()
Removes a Page (Route Model)
Adds a Document (RouteDocument Model).
Calls RouterService.createSeries()
Creates a Document (RouteDocument Model)
Edits a Document (RouteDocument Model).
Calls RouteService.updateSeries()
Updates a Document (RouteDocument Model)
Removes a Document (RouteDocument Model).
Calls RouteService.destroySeries()
Destroys a Document (RouteDocument Model)
RenderGenericService is a Proxy-Generics service. This module has a default render if none is specified.
Renders a markdown document using Markdown-it and all the plugins configured in proxyGeneric.render_service
@returns
{
meta: <{Object}>, // The Meta Data from the Document
document: <{String}> // The Rendered HTML of the Document
}
FAQs
Router for Proxy Engine
The npm package trailpack-proxy-router receives a total of 3 weekly downloads. As such, trailpack-proxy-router popularity was classified as not popular.
We found that trailpack-proxy-router demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.