Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Tip
titlePrerequisite

These methods are introduced in openmrs-module-webservices.rest >= 2.20.0

So upgrade the openmrs-module-webservices.rest dependency version in your modules pom.xml if necessary.

Before we get Started on how to get a Resource to be in the OpenMRS Swagger Documentation we should be comfortable with the concept of Resources and SubResources in OpenMRS.

1. Resources are OpenMRS objects (persons, patients, encounters, observations, etc.) which are exposed by the REST Web Services modules as a REST resources

2. SubResources are those resources(PersonNames, PersonAddresses, ConceptNames, etc) are not defined or do not make sense apart from their parent object. We refer to these as subresources

So now ,for a resource to be appeared in OpenMRS Swagger Documentation, one should override these methods, based on its supported CRUD operations.

  1. Model getGETModel(Representation)

...

  1.      A resource that supports

...

  1. `GET` operations such as 'getAll', 'getByUniqueId', and 'search'' should override this method.                                                        
  2. Model getCREATEModel(Representation)

...

  1.      A resource that supports

...

  1. `CREATE` operations should override this method.
  2. Model getUPDATEModel(Representation)

...

  1.      A resource that supports

...

  1. `UPDATE` operations should override this method.


It is not mandatory that you You do not need to override these methods. However, if not, then their proper definitions won't appear in OpenMRS Swagger Specspecification. Thus the resource won't show up in the live documentation here (while the live demo swagger documentation can be found inside the advanced system adminstration section of the reference application on the demo server) either.

These methods are introduced in openmrs-module-webservices.rest >= 2.20.0

...

So it's recommended that you override these.

...

titlePrerequisite

.

How to find which properties to be documented?

 getGETModel(Representation), getCREATEModel(Representation), and getUPDATEModel(Representation) methods correspond to getGetRepresentation(), getCreatableProperties(), and getUpdatableProperties() methods respectively. So they can be used as reference when documenting resources.

One can also look into corresponding test classes and its supportedClass

Example 
Example 

When documenting OrderSetResource1_12 one can use OrderSet.class, OrderSetResource1_12Test, and OrderSetController1_12Test as reference.

Documenting GET representation of a resource

Model   getGETModel(Representation)

This method should return a Swagger Model object representing the GET representation schema for that resource. Returned Model may change depending on the representation type (DEFAULT,  FULLFULL, REF) being passed to that method.

If you don’t don't understand the difference between DEFAULT, FULL, and REF representations, please refer to: 

REST Web Services API For Clients - Representations

Let's begin by documenting OrderSetResource1_12 12 

Its DEFAULT representation returns a JSON object with the following properties:

{ uuid, display, name, description, retired, operator, orderSetMembers }

  • 'uuid', 'display', 'name', 'description'
  • are
  •  are just strings. 
  • 'retired'
  • can
  •  can be either true or false.
  • 'operator'
  • can takes
  •  can take the values ALL, ONE,
  • or
  • or ANY
  • 'orderSetMembers' is an array containing REF representations of OrderSetMember resources.

Based on the type of its properties, we can document the getGETModel for OrderSet resource as follows:

Code Block
languagejava
titleOrderSetResource.java
public Model getGETModel(Representation rep) {
    ModelImpl model = (ModelImpl) super.getGETModel(rep);
    if (rep instanceof DefaultRepresentation || rep instanceof FullRepresentation) {
        model
            .property("operator", new EnumProperty(OrderSet.Operator.class));
    }
    if (rep instanceof DefaultRepresentation) {
        model
            .property("orderSetMembers", new ArrayProperty(new RefProperty("#/definitions/OrdersetOrdersetmemberGetRef")));
    } else if (rep instanceof FullRepresentation) {
        model
            .property("orderSetMembers", new ArrayProperty(new RefProperty("#/definitions/OrdersetOrdersetmemberGet")));
    }
    return model;
}

As you could see, the properties: uuid, display, name, description, and retired are not documented because they are inherited by the overridden method of its superclass. If they aren’t inherited, they should be added like:

Code Block
languagejava
model
  .property("uuid", new StringProperty())
  .property("display", new StringProperty())
  .property("name", new StringProperty())
  .property("retired", new BooleanProperty());

...

Code Block
languagejava
titleConceptNameResource1_8.java
@SubResource(parent = ConceptResource1_8.class, path = "name", ..)
 public class ConceptNameResource1_8

As shown in the example, the definition name of  name of ConceptResource1_8 is Concept is Concept (identified by the the name property  property its @Resource @Resource annotation) . So the definition name of ConceptNameResource1_8 sub-resource should be ConceptName. As you see, the definition name of a sub-resource is retrieved by appending the value of the the path property  property of its @SubResource annotation  annotation to its parent's name.

RefProperty Type Type 

When one resource include includes another resource as its property   (e.g., conceptDatatype property on Concept object), the FULL representation of that property object is never included in the parent.

Eg :- DEFAULT representation of Concept resource include includes the following reference properties:

name, datatype, conceptClass

name is  is a ConceptNameResource, datatype is  is a ConceptDatatypeResource, conceptClass is  is a ConceptClassResource.

In DEFAULT representation of a Concept resource

  • DEFAULT representation
  • of
  • of name
  • is
  •  is included
  • REF representation
  • of
  • of datatype
  • is
  •  is included
  • REF
  • representation
  • representation conceptClass
  • is
  •  is included

So the code would be like:

Code Block
languagejava
model
  .property("name", new RefProperty("#/definitions/ConceptNameGet"))
  .property("datatype", new RefProperty("#/definitions/ConceptdatatypeGetRef"))
  .property("conceptClass", new RefProperty("#/definitions/ConceptclassGetRef"));

...