Friday, September 04, 2020

OIC: How to configure endpoints of ORDS Connections in OIC?

This article discussed how to configure the endpoint of a Connection to an ORDS REST service (AutoREST or REST Module) in such a way that you have the right part of the URI in the right place and can easily refactor it or promote your application to another environment.

To call Oracle Rest Data Services (ORDS) from an Oracle Database (DBCS or ATP) you create a REST Invoke Connection (not also Trigger, as the DB will not call you back).

To make the database supporting ORDS you must enable REST Services on the schema whereby you configure an alias, for example "my_schema_alias" which becomes part of the URL of the endpoint of the REST service. The question is where to put that alias: in the configuration of the Connection or in the relative resource URI's in the Integrations?

Best practice is making it part of the URL in the Connection, which then would be something like https://[my-ords-instance].[my-data-center].oraclecloudapps.com/ords/my_schema_alias/.

OIC REST Connection to ORDS

  The relative resource URI's to configure in the Integrations that use a Connection leveraging the AutoREST services on a table called “my_table” (or “jk_test” as in the picture below) would look something like:

  • /my_table/ 
  •  /my_table/{id}

 

Integration Invoke Activity Configuration

 

This makes the endpoint accessing that resource something like https://[my-ords-instance].[my-data-center].oraclecloudapps.com/ords/my_schema_alias/my_table/.

Rationale being that for different environments (for example DEV, TEST, ACC, PROD) you might want to use a different alias in each individual Connector to prevent accidental calls to the wrong environment (for example a call from an Integration on a TEST environment still pointing to the DEV database schema). This also supports having the schemas for DEV, TEST etc. in one and the same database instance, each schema having its own alias. In contrast, if you made the alias part of the relative resource URI of the Integration instead (/my_schema_alias/my_table/ in the example) you then must modify the relative resource URI in the Integration to activate it on another environment. This requires extra testing and would frustrates a build-once-deploy-many CI/CD strategy.

Let’s assume you have a couple of main applications that store their data in the database using ORDS and use Integrations for that. When they all use the same database schema, you have the option to create one generic Connection for all applications or create a specific one for each separate application.

Best practice is to have a specific Connection per (main) application.

Rationale is that this supports having different connection settings (Connection URL, Identity key store alias name, Security) for different applications. Among others, this supports an easy change for one of those applications to use a different schema without the need of introducing a new Connection and having to reconfigure Integrations to use that new Connection. This is also something you want to prevent when applying a build-once-deploy-many CI/CD strategy where applications are developed using the same schema but in Production each will use its own.

An alternative to using AutoREST on tables, you can also create RESTful Service Modules. A RESTful Service Module is a grouping of common templates, known as resource templates, under a common Uniform Resource Identifier (URI) prefix. At my current customer we only use (generated) REST Modules. Inside a REST Module you create so-called “Templates” that each have a URI pattern. A template groups one or more REST Handlers (of type GET, POST, PUT or DELETE) for one and the same resource.

The URI prefix of a REST Module will be concatenated to the alias of the schema that I already discussed. Let’s assume my REST Module has the URI-prefix "/my_module/". A similar question comes up now: where to put the REST Module prefix, in a module-specific Connector or in the relative resource URI in the Integrations?

Best practice in this case depends on the granularity of your REST Modules:

  • Course-grained (typically being one REST Module per main application): use a Connection per REST Module which will include the URI-prefix. Rationale: in this way you don't have to include that prefix in every relative resource URI in every Integration of that application.

  • Fine-grained (typically being a REST Module per main resource): use one Connection per main application but without the URI-prefix. Instead the URI-prefix is included in the relative resource URI of the Integrations. Rationale: if you include the prefix in the Connection, you must also create a Connection per REST Module. Assuming you have many resources this will result in many Connections to create and configure.

 

ORDS REST Module Definition
  

The example in the above picture concerns a schema with alias is “sb_store”, containing a REST Module with name Generic that has URI prefix “/gn/”, on its turn containing a Template that has URI pattern “faults/”. The endpoint to a GET REST Handler would then be like:

https://[my-ords-instance].[my-data-center].oraclecloudapps.com/ords/sb_store/gn/faults/.

This article will not discuss why you should choose one type of granularity over the other, other than that this is influenced by aspects like how many developer you want be able to do simultaneous development, impact on the amount of REST Modules and the impact this may have on the complexity of deployment and that you probably will choose for fine-grained when resources are  shared by applications where each individual resource is treated as a kind of “microservice”. When you generate your REST Modules you probably use a course-grained approach.