Tag Archives: Swagger UI

Attributes for Documenting TEMSDataSetResource

Attributes for Documenting TEMSDataSetResource

I recently blogged about a number of RAD Server topics, including using TEMSDataSetResource, (the component that enables a TDataSet to be expose as a RESTful resource, and manage all the List, Get, Put, Post, Delete methods – very cool!), how to set named parameters for the TEMSDataSetResource documentation (where multiple keys are passed in e.g. with Master Detail relationships (reviewed below)), and how the YAML and JSON documentation is auto generated with custom RESTful resources / end points

Typically, each custom REST endpoint method (List, Get, Put, Post, Delete), would be supported by separate procedures in the code, with each having their attributes to support documentation, resource name etc.

Typically, List and Post would have no parameters, but Get, Put and Delete would all take the ID of the object being requested / updated / removed. The approach with separate procedures in code makes it very easy to add attributes to list parameters based on their method. Which leads me to the challenge with TEMSDataSetResource. How do you define parameters for the different methods with the same component?

ResourceSuffix Attribute

In the last blog, I highlighted how the ResourceSuffix can be used to set the name of values in the resource, rather than using the default ‘id’ value. – This is essential when multiple parameters are used.

[ResourceName('exams')]
  TExamsResource1 = class(TDataModule)
  [ResourceSuffix('./{EXAM_ID}/questions')]
  [ResourceSuffix('List', './')]
  [ResourceSuffix('Get', './{QUESTION_ID}')]
  [ResourceSuffix('Post', './')]
  [ResourceSuffix('Put', './{QUESTION_ID}')]
  [ResourceSuffix('Delete', './{QUESTION_ID}')]
  dsrEXAM_QUESTIONS: TEMSDataSetResource;

The documentation picks up the parameter name automatically into the YAML documentation for that method. But now it needs to be defined. In this example, EXAM_ID is required for each call, and QUESTION_ID is also required, but only for the Get, Put and Delete.

EndPointRequestParameter Attribute

To define the required attribute EXAM_ID, it is possible to use a single EndPointRequestParameterAttribute (note: Attribute part of the name at the end is optional)

[EndPointRequestParameter(
   TAPIDocParameter.TParameterIn.Path, 
   'EXAM_ID', // Param name
   'EXAM_ID for the selected /exam/ ', //about it 
   true, // required
   TAPIDoc.TPrimitiveType.spInteger, // type
   TAPIDoc.TPrimitiveFormat.Int64, // ext format
   TAPIDoc.TPrimitiveType.spInteger, // array?
   '', // Scheme
   '')] // Reference
dsrEXAM_QUESTIONS: TEMSDataSetResource;

But here in lies the twist….. If we did the same for QUESTION_ID, we would have issues with it showing for List  and Post. The answer (once found) is actually quite simple. You need to define the parameters in the same way as the ResourceSuffix. e.g.

[EndPointRequestParameter(
   'Get',
   TAPIDocParameter.TParameterIn.Path, 
   'QUESTION_ID', // Param name
   'QUESTION_ID for the question to get', //desc
   true, // required
   TAPIDoc.TPrimitiveType.spInteger, // type
   TAPIDoc.TPrimitiveFormat.Int64, // ext format
   TAPIDoc.TPrimitiveType.spInteger, // array?
   '', // Scheme
   '')] // Reference
[EndPointRequestParameter(
   'Put',
   TAPIDocParameter.TParameterIn.Path, 
   'QUESTION_ID', // Param name
   'QUESTION_ID for question to update', //desc
   true, // required
   TAPIDoc.TPrimitiveType.spInteger, // type
   TAPIDoc.TPrimitiveFormat.Int64, // ext format
   TAPIDoc.TPrimitiveType.spInteger, // array?
   '', // Scheme
   '')] // Reference
[EndPointRequestParameter(
   'Delete',
   TAPIDocParameter.TParameterIn.Path, 
   'QUESTION_ID', // Param name
   'QUESTION_ID for the question to delete ', 
   true, // required
   TAPIDoc.TPrimitiveType.spInteger, // type
   TAPIDoc.TPrimitiveFormat.Int64, // ext format
   TAPIDoc.TPrimitiveType.spInteger, // array?
   '', // Scheme
   '')] // Reference
dsrEXAM_QUESTIONS: TEMSDataSetResource;

The issue here however, is that as soon as you define method specific attributes, you stop inheriting the defined parameters for the TEMSDataSetResource. This means you need to define all of parameters them for that method. (so you need to add in the EXAM_ID again for each of the Get, Put and Delete methods with extra EndPointRequestParameter’s) e.g..

[EndPointRequestParameter(
   'Get',
   TAPIDocParameter.TParameterIn.Path, 
   'EXAM_ID', // Param name
   'EXAM_ID for the exam to get', //desc
   true, // required
   TAPIDoc.TPrimitiveType.spInteger, // type
   TAPIDoc.TPrimitiveFormat.Int64, // ext format
   TAPIDoc.TPrimitiveType.spInteger, // array?
   '', // Scheme
   '')] // Reference
[EndPointRequestParameter(
   'Get',
   TAPIDocParameter.TParameterIn.Path, 
   'QUESTION_ID', // Param name
   'QUESTION_ID for question to update', //desc
   true, // required
   TAPIDoc.TPrimitiveType.spInteger, // type
   TAPIDoc.TPrimitiveFormat.Int64, // ext format
   TAPIDoc.TPrimitiveType.spInteger, // array?
   '', // Scheme
   '')] // Reference
...

EndPointRequestSummary Attribute

The same approach can also be used for the EndPointRequestSummaryAttribute.

 [EndPointRequestSummary
  ('Exams', // Tags
   'Exams', // Summary
   'Each Exam has a list of questions, each containing multiple answers', // Description
   'application/json', // Produces
   '')] // Consumes

or 

 [EndPointRequestSummary
  ('Get',  // Method
  'Exams', // Tags
  'Exams', // Summary
  'Fetches an specific Exam', // Description
  'application/json', // Produces
  '')] // Consumes

etc

More about attributes…

See Custom_API_Documentation on DocWiki

Master Detail data in RAD Server using TEMSDataSetResource

Master Detail data in RAD Server

The TEMSDataSetResource is a very powerful component that enables rapid development of full document REST API’s for TDataSet using RAD Server. Using TEMSDataSetResource, along with traditional master detail relationship configurations, it is possible to expose, and automatically document data APIs via REST with no code at all.

In this article, I will cover sharing master detail data with no code, but also how to roll your own REST endpoint to cover more advanced detail with detail embedded calls.

In my previous article, I updated advise on getting started with Swagger UI, using the new WebFiles feature of RAD Server (from 10.3.2) as a way to view your documentation as you build your backend services API. This article will build upon the sample application created in that post.

Continue reading Master Detail data in RAD Server using TEMSDataSetResource

Embedding Swagger UI into RAD Server

This post is an update to the original post written previously showing Swagger UI being used with RAD Server, covering new features of RAD Server.

Why Embed Swagger UI into RAD Server?

Swagger UI (as previously discussed) is a great option for checking your documentation and working with the REST API. One of the challenges has always been CORS (Cross Origin Resource Sharing) that makes execution of the code a challenge when developing.

There are a few options now however. You can either work around this with browser plug-ins, (as seen before), enable CORS in the emsserver.ini under [Server.APICrossDomain], or embed swagger-ui inside your RAD Server instance.

In this video, I cover the latter option. You can watch how to get documentation up and running. The video shows how to configure your EMSServer.ini to share the external resource through RAD Server and also modify the downloaded files to automatically load up the API documentation directly from RAD Server.

WebFiles in RAD Server EMSServer.ini

The key to making this work is the WebFiles option that was added to RAD Studio in 10.3.2. This was primarily added to make it easier to serve out web content and support ExtJS for doing web client development under the Architect edition of RAD Studio, however, this also has the benefit of making other content available to share.

Continue reading Embedding Swagger UI into RAD Server

Swagger / YAML and self documenting RESTful API’s

Get your Swagger on with Delphi

So you want to build a new REST server (using Delphi or C++) and want it to become really popular and easily used by other developers. Imagine….

  • Your building a new REST server,
  • You have to document the API’s
  • You have to keep the documentation updated
  • To aid adoption of your services you want to create examples for other developers to connect into your server quickly

With the release of RAD Studio 10.1 Berlin, it is now possible to do all the above thanks to the new documentation attributes used in EMS packages that create YAML documentation that can be used with Swagger.

What is YAML?

YAML: (rhymes with “camel”) YAML Ain’t Markup Language

In short, YAML is a human friendly data serialization standard for all programming languages that is a subset of JSON.

Both JSON and YAML aim to be human readable data interchange formats. However, JSON and YAML have different priorities. JSON’s foremost design goal is simplicity and universality. Thus, JSON is trivial to generate and parse, at the cost of reduced human readability. It also uses a lowest common denominator information model, ensuring any JSON data can be easily processed by every modern programming environment.

In contrast, YAML’s foremost design goals are human readability and support for serializing arbitrary native data structures. Thus, YAML allows for extremely readable files, but is more complex to generate and parse. In addition, YAML ventures beyond the lowest common denominator data types, requiring more complex processing when crossing between different programming environments.

YAML can therefore be viewed as a natural superset of JSON, offering improved human readability and a more complete information model. This is also the case in practice; every JSON file is also a valid YAML file. This makes it easy to migrate from JSON to YAML if/when the additional features are required.

What is Swagger?

Swagger is a simple yet powerful representation of your RESTful API, and as part of the open tools initiative (joining November 2015) it is backed by members such as Microsoft, Google, PayPal and IBM.

Using a YAML document, you can create Swagger instance of your API.

With the largest ecosystem of API tooling on the planet, thousands of developers are supporting Swagger in almost every modern programming language and deployment environment making it a great choice to make your REST server easily integrated and used by others.

With a Swagger-enabled API, you get interactive documentation, client SDK generation and discoverability.

Creating YAML with Delphi / C++ Builder

To gain the benefits of Swagger you need to create the YAML documentation; this is achieved using a number of new attributes defined on the custom API’s you are creating. The three core Custom API Documentation attributes are:

In addition there are two additional documentation elements that allow you to define EndPointObjects that are used by your API. This way you define structures that are returned, rather than just returning simple types.

Custom API Documentation Sample

With Rad Studio 10.1 Berlin, in the samples, there is a new demo that covers the above custom api documentation attributes. If you want to open it in the IDE, choose “Open a sample project” and browse to the following folder and open the APIDocDelphiAttributes.bpl package (cpp equivalents also available, swap Delphi for CPP in names).

 \Samples\Delphi\Database\EMS\APIDocAttributes

As this sample uses InterBase, you need to make sure you have started InterBase. If its not running, use the IBServerManager to make sure its running. 

Rather than cover each of the attributes here, and repeat the documentation, I’ll leave you explore the links above to read up on these attributes, instead I want to use this sample to explore the YAML using Swagger UI, but first lets get the YAML document by running the sample.

Getting YAML from EMS Sample

Compile and run (F9) the sample project and choose Open Browser. You should now see a call to http://localhost:8080/version showing version 2.1 or higher.EMS Version

To get the documentation from the server, navigate to http://localhost:8080/api where you will see the different documentation types supported. EMS API

This shows 2 currently. apidoc.yaml and apidoc.json. Add these to the end of the API url to see how they look. e.g. http://localhost:8080/api/apidoc.yaml

EMS APIDoc YAML
http://localhost:8080/api/apidoc.yaml returning YAML from use with Swagger from EMS

YAML to Swagger UI

So you have a YAML document.. now what? Swagger UI is a great tool for reading the YAML document and giving you interactive HTML documentation for your RESTful API.

You can download the latest Swagger UI from GitHub onto your development machine https://github.com/swagger-api/swagger-ui

Download Swagger UI
Download Swagger UI

Unzip the download on your development machine / vm. In there locate the dist folder and open the index.html

A note on CORS

Now before we go any further, your need to be aware of CORS – Cross Origin Resource Sharing. In short, because we will want to enable PUT, POST, DELETE from outside the core domain, we need to allow CORS (or you will not be able to call EMS)

You can either update the EMS configuration to allow CORS or install the following google chrome plugin. If you install the plugin, once you have the SwaggerUI index.html page open, you need to make sure its enabled. (i’ve sometimes found I’ve had to disable and re-enable it to get it to work).

Enabling CORS using Google Chrome Plugin
Enabling CORS using Google Chrome Plugin

Loading the YAML into Swagger

Copy the URL for the YAML document and post it into your SwaggerUI/dist/index.html page, and choose Explore.

The sample (pet store) documentation in SwaggerUI will now be replaced with the documentation form the EMS server.

You can now browse and invoke the API calls directly from the SwaggerUI interface. The example creates a category called Sample Tag (which you can see listed) All the other categories cover the default features of EMS, including User security, and the new ThingPoint EdgeModule API’s

Visualising YAML in Swagger UI
Visualising YAML in Swagger UI

You can now explore the categories, review the documentation model that defines the structure being return (thanks to the EndPointObjectXXX attributes)Viewing Swagger UI exposed Methods

… and once you fill in any defined parameters you can “Try It Out”. This shows the URL called, and also the response body!

Trying out Swagger UI
Trying out Swagger UI

That is it! How simple to test you RESTful API than by using YAML and Swagger UI.

You can now explore Swagger.IO and learn about the other languages that you can create connections into your EMS server with 🙂