API Service Template

We should have a common template for all services in our API. This allows for easier comprehension and a cleaner code base overall.

All Services should contain:

Transactions

  • The @Transactional annotation should be at the top of the service interface

  • Methods that don't write data should also put before their methods

    @Transactional( readOnly = true)

Authentication

  • Each method in the interface should have an @Authorized annotation on it

@Authorized(OpenmrsConstants.PRIV_EDIT_THINGS)
  • Data should have these privileges (users, encounters, orders):

    • PRIV_ADD_THINGS

    • PRIV_EDIT_THINGS

    • PRIV_VIEW_THINGS

    • PRIV_DELETE_THINGS

    • PRIV_PURGE_THINGS

  • Metadata should have these privileges (encounterType, concepts, program, location):

    • PRIV_MANAGE_THING_TYPES (covers add/edit/delete)

    • PRIV_VIEW_THING_TYPES

    • PRIV_PURGE_THING_TYPES

Parent classes

  • All service interfaces should extend org.openmrs.api.OpenmrsService

  • All service implementation classes should extend org.openmrs.api.BaseOpenmrsService

Commenting

In Eclipse, Alt-Shift-J is your friend...or Alt-Command-J on a Mac.

  • Service interface:

    • Should have class level comment explaining a typical use case

    • Each method should have comment about what it does, each parameter explained, and return value explained

    • Deprecated methods should be marked in the javadoc and given a comment about why and what replaces it.

  • Service implementation:

    • The class comment on the should explain and point back at the interface

    • Each method should simply point at the interface

  • DAO interface

    • Should have class level comment should point back at the interface

    • Each method comment should simply point at the interface

  • DAO implementation

    • Class level comment should point at DAO and service interface

    • Each method should point at service interface (and DAO?)

General

  • Enumerations should be used instead of numerical constants

Retired vs Voided

  • DATA is defined as what is contained in the database as patient information or user defined explanation of metadata

  • META DATA is defined as those tables that describe how to store and what is the DATA

  • Data should be voided. Meta data should be retired

Data

Meta Data

Data

Meta Data

  • Cohort

  • ComplexObs

  • Obs

  • Encounter

  • Order

  • Person

  • User

  • Patient

  • PatientIdentifier

  • PersonName

  • PersonAddress

  • PersonAttribute

  • Program

  • etc

  • Concept

  • ConceptClass

  • ConceptDataType

  • EncounterType

  • Location

  • PersonAttributeType

  • PatientIdentifierType

  • OrderType

  • etc

Thing Service

@Transactional public interface ThingService extends OpenmrsService {   /** * @see #saveThing(Thing) * @deprecated replaced by saveThing(Thing) */ @Authorized({OpenmrsConstants.PRIV_CREATE_THINGS}) public void createThing(Thing thing) throws APIException;   /** * Gets a Thing by identifier * @param thindId identifier of desired Thing */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public Thing getThing(Integer thingId) throws APIException;   /** * Get a Thing by name * @param thingName is the exact name of the desired Thing */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public Thing getThing(String thingName) throws APIException; // if this is meaningful   /** * Get a Thing by GUID * @param guid is the guid of the desired Thing */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public Thing getThingByGuid(String guid) throws APIException; // add this later for sync   /** * Gets all Things, [including retired|not including voided] */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public List<Thing> getAllThings() throws APIException; // includes retired, but not voided   /** * Gets all Things * @param include[Retired|Voided] whether or not to include [retired|voided] Things */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public List<Thing> getAllThings(boolean includeRetired) throws APIException; // only one of these public List<Thing> getAllThings(boolean includeVoided) throws APIException; // only one of these   /** * Find Things * @param query partial name * @returns matching Things */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public List<Thing> getThings(String query);   /** * Get Things that match the given properties * @param ... */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public List<Thing> getThings( ... all properties ... ) throws APIException;   /** * Get Things by XXX * @param xxx */ @Authorized({OpenmrsConstants.PRIV_VIEW_THINGS}) public List<Thing> getThingsByXXX(XXX xxx) throws APIException; // where XXX is metadata // in most instances, will delegate to getThings(...all properties...)   /** * @see #saveThing(Thing) * @deprecated replaced by saveThing(Thing) **/ @Authorized({OpenmrsConstants.PRIV_EDIT_THINGS}) public void updateThing(Thing thing) throws APIException;   /** * Save Thing in database * @param thing Thing to be saved */ @Authorized({OpenmrsConstants.PRIV_EDIT_THINGS}) public Thing saveThing(Thing thing) throws APIException;   /** * [Retires|Voids] Thing * @param thing Thing to be [retired|voided] */ @Authorized({OpenmrsConstants.PRIV_EDIT_THINGS}) public Thing retireThing(Thing thing) throws APIException; // for metadata, retired returned in getAll public Thing voidThing(Thing thing) throws APIException; // for data, voided not returned in getAll   /** * [Unretired|Unvoid] Thing * @param thing to be recovered */ @Authorized({OpenmrsConstants.PRIV_EDIT_THINGS}) public Thing unretireThing(Thing thing) throws APIException; // for metadata public Thing unvoidThing(Thing thing) throws APIException; // for data   /** * Remove Thing completely (not reversible) * @param thing Thing to be purged from the database */ @Authorized({OpenmrsConstants.PRIV_PURGE_THINGS}) public Thing purgeThing(Thing thing) throws APIException;   /** * Remove Thing completely (not reversible) * @param thing Thing to be purged from the database * @param cascase if <code&gt;true&lt;/code>, related data are purged as well */ @Authorized({OpenmrsConstants.PRIV_PURGE_THINGS}) public Thing purgeThing(Thing thing, boolean cascade) throws APIException;   /** * Remove Thing completely (not reversible) * @param thing Thing to be purged from the database * @deprecated use #purgeThing(Thing) */ @Authorized({OpenmrsConstants.PRIV_PURGE_THINGS}) public void deleteThing(Thing thing) throws APIException;