mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-17 20:50:44 +00:00
Add initial version of javalin documentation
This commit is contained in:
@ -91,7 +91,7 @@ And then having a bug in the check permission logic on the _Light Bulb Inventory
|
|||||||
No!
|
No!
|
||||||
|
|
||||||
All of the (really important, even though application developers hate doing it) aspects of security - you don't need to write ANY code for dealing with that.
|
All of the (really important, even though application developers hate doing it) aspects of security - you don't need to write ANY code for dealing with that.
|
||||||
Just tell QQQ what Authentication provider you want to use (e.g., https://auth0.com/[Auth0]), and - to paraphrase the old https://www.youtube.com/watch?v=YHzM4avGrKI[iMac ad] - there's no step 2.
|
Just tell QQQ what Authentication provider you want to use (e.g., OAuth2 or https://auth0.com/[Auth0]), and - to paraphrase the old https://www.youtube.com/watch?v=YHzM4avGrKI[iMac ad] - there's no step 2.
|
||||||
QQQ just does it.
|
QQQ just does it.
|
||||||
|
|
||||||
''''
|
''''
|
||||||
|
@ -31,11 +31,9 @@ include::metaData/PermissionRules.adoc[leveloffset=+1]
|
|||||||
|
|
||||||
== Services
|
== Services
|
||||||
|
|
||||||
|
include::misc/Javalin.adoc[leveloffset=+1]
|
||||||
include::misc/ScheduledJobs.adoc[leveloffset=+1]
|
include::misc/ScheduledJobs.adoc[leveloffset=+1]
|
||||||
|
|
||||||
=== Web server (Javalin)
|
|
||||||
#todo#
|
|
||||||
|
|
||||||
=== API server (OpenAPI)
|
=== API server (OpenAPI)
|
||||||
#todo#
|
#todo#
|
||||||
|
|
||||||
|
109
docs/misc/Javalin.adoc
Normal file
109
docs/misc/Javalin.adoc
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
== QQQ Middleware: Javalin web server
|
||||||
|
include::../variables.adoc[]
|
||||||
|
|
||||||
|
QQQ provides a standard implementation of a middleware layer - that is - code that exists between the
|
||||||
|
QQQ backend and user interface. This implementation is a web server built using the https://javalin.io/[Javalin framework],
|
||||||
|
packaged and deployed in the `qqq-middleware-javalin` maven module
|
||||||
|
|
||||||
|
The de facto way to create a QQQ application server is to write a class which uses an instance of one of the
|
||||||
|
subclasses of `QApplicationJavalinServer`.
|
||||||
|
|
||||||
|
For example, if your application metadata is defined in a directory of yaml files, your server class could be implemented as:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
.ConfigFileBasedQQQApplication usage example
|
||||||
|
----
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String path = "src/main/resources/metadata";
|
||||||
|
ConfigFilesBasedQQQApplication application = new ConfigFilesBasedQQQApplication(path);
|
||||||
|
QApplicationJavalinServer javalinServer = new QApplicationJavalinServer(application);
|
||||||
|
javalinServer.start();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.error("Failed to start javalin server. See stack trace for details.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
A similar class exists if your metadata is produced by a package of Java MetaDataProducer objects: `MetaDataProducerBasedQQQApplication`.
|
||||||
|
|
||||||
|
=== QApplicationJavalinServer
|
||||||
|
This class provides the bridge between your QQQ Application (e.g., your metadata) and the QQQ Middleware layer
|
||||||
|
served by a Javalin web server. It has several properties to control behaviors:
|
||||||
|
|
||||||
|
* `Integer port` - (default `8000`) - port to use for serving HTTP.
|
||||||
|
* `boolean serveFrontendMaterialDashboard` - (default `true`) whether to serve the javascript frontend provided
|
||||||
|
in the maven artifact `qqq-frontend-material-dashboard`.
|
||||||
|
* `boolean serveLegacyUnversionedMiddlewareAPI` - (default `true`) whether to serve a version the original implementation
|
||||||
|
of the QQQ middleware, which current version of `qqq-frontend-material-dashboard` are compatible with.
|
||||||
|
* `List<AbstractMiddlewareVersion> middlewareVersionList` - (default contains `MiddlewareVersionV1`) - list of
|
||||||
|
newer, formally versioned implementations of the QQQ middleware interface to be served.
|
||||||
|
* `Consumer<Javalin> javalinConfigurationCustomizer` - (default `null`) - optional hook to customize the
|
||||||
|
javalin service object before it is started.
|
||||||
|
* `List<QJavalinRouteProviderInterface> additionalRouteProviders` - (default `null`) - list of fully custom
|
||||||
|
implementations of `QJavalinRouteProviderInterface`, to add additional endpoints to the javalin server.
|
||||||
|
** _Note, you may first want to consider using JavalinRouteProviderMetaData instead - see below._
|
||||||
|
* `QJavalinMetaData javalinMetaData` - (default `null`) - optional alternative place to define `JavalinMetaData` (vs.
|
||||||
|
defining it in the `QInstance`). _Note that if it is set in both places, the one in the QApplicationJavalinServer
|
||||||
|
is used._
|
||||||
|
|
||||||
|
=== JavalinMetaData
|
||||||
|
Certain behaviors of a QQQ Javalin server are configured in a declarative manner by adding a `QJavalinMetaData`
|
||||||
|
object to the `supplementalMetaData` in your `QInstance` (or, as mentioned above, by setting it directly on the
|
||||||
|
`QApplicationJavalinServer`):
|
||||||
|
|
||||||
|
* `List<JavalinRouteProviderMetaData> routeProviders` - (default `null`) optional list of custom route providers to
|
||||||
|
add to the Javalin server. See below for details.
|
||||||
|
* `String uploadedFileArchiveTableName` - (default `null`) - reference to a QQQ Table in your application instance,
|
||||||
|
needed to support the Bulk Load process, as well as any other processes which need to accept an uploaded file
|
||||||
|
as input.
|
||||||
|
* `boolean loggerDisabled` - (default `false`)
|
||||||
|
* `Function<QJavalinAccessLogger.LogEntry, Boolean> logFilter` - (default `null`)
|
||||||
|
* `boolean queryWithoutLimitAllowed` - (default `false`)
|
||||||
|
* `Integer queryWithoutLimitDefault` - (default `1000`)
|
||||||
|
* `Level queryWithoutLimitLogLevel` - (default `INFO`)
|
||||||
|
|
||||||
|
==== JavalinRouteProviderMetaData
|
||||||
|
This type of metadata allows you to add additional http route providers to your Javalin instance, e.g., for
|
||||||
|
serving static files or for running custom code from your application (in the form of QQQ Processes) to respond
|
||||||
|
to HTTP requests.
|
||||||
|
|
||||||
|
* `String hostedPath` - (required)
|
||||||
|
* `String fileSystemPath` - (required for a static router)
|
||||||
|
* `String processName` - required for a dynamic, process-based router. Must be a process name within the QQQ Instance.
|
||||||
|
See below for additional details
|
||||||
|
* `List<String> methods` - required list of HTTP methods (verbs) that are served by the route provider
|
||||||
|
* `QCodeReference routeAuthenticator - Optional reference to a class that implements `RouteAuthenticatorInterface`,
|
||||||
|
to provide security authentication to all requests handled by the route provider.
|
||||||
|
** A default implementation is provided as `SimpleRouteAuthenticator`, which requires that a user session be present
|
||||||
|
to access paths served by the route provider.
|
||||||
|
|
||||||
|
===== Process-based route provider processes
|
||||||
|
If you define a `JavalinRouteProviderMetaData` with a `processName` (e.g., to serve dynamic HTTP responses from your javalin
|
||||||
|
server), the process that you implement will be called to respond to any HTTP requests received by the javalin
|
||||||
|
server which match the `hostedPath` and `methods` that are specified in the metadata.
|
||||||
|
|
||||||
|
The QQQ javalin server will marshal request data from the javalin context into the process's payload, conforming to
|
||||||
|
the shape of the `ProcessBasedRouterPayload` class. Similarly, the http response will be built by taking values from
|
||||||
|
the process's output/state conforming to the fields in that class. As such, it is recommended to use a
|
||||||
|
`ProcessBasedRouterPayload` instance, as show in this example:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
.Process-based router usage example (including ProcessBasedRouterPayload)
|
||||||
|
----
|
||||||
|
public class MyDynamicSiteProcessStep implements BackendStep
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run(RunBackendStepInput input, RunBackendStepOutput output) throws QException
|
||||||
|
{
|
||||||
|
ProcessBasedRouterPayload payload = input.getProcessPayload(ProcessBasedRouterPayload.class);
|
||||||
|
String path = payload.getPath();
|
||||||
|
payload.setResponseString("You requested: " + path);
|
||||||
|
output.setProcessPayload(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
Reference in New Issue
Block a user