Versions Compared

Key

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

This guide walks a core developer through adding a new set of web service methods for a core object.  It is a similar process for module developers, but for that setup, see ? Adding a Web Service Step by Step Guide for Module Developers (REST 1.x)

...

The first thing to do is to read through the conventions section on the ?REST Web Services API For Clients.  This outlines the very basics of the how to name the urls, design the objects, etc.

...

  1. In the org.openmrs.module.webservicesyourmoduleid.rest.resource package, create a new class that extends MetaDataDelegatingCrudResource<Location>.
    1. public class LocationResource implements MetaDataDelegatingCrudResource<Location>
      1. The MetaDataDelegatingCrudResource and DataDelegatingCrudResource class are helper classes for "data" and "metadata" OpenmrsObjects.
      2. The DelegatingCrudResource super class can be used for any other object type
      3. Its also possible to not have a resource class for some simple rest urls.  See the SessionController class.
  2. Add @Resource("location") annotation to the class.
    1. This tells the framework to put the resource at uri location: /ws/rest/location/uuid
    2. By convention, resource names are all lower case.
  3. Add @Handler(supports = { Location.class }, order=0) annotation to the class.
    1. This allows the webservices.rest module to easily and automatically find our resource.
    2. The module can now look for "any Handler for class Location of type CrudResource" and use that for the json/xml translation
    3. The "order" element means this class has lowest precedence and can be overridden by a module-provided resource for Location
  4. Expose properties that are on the Location object through the resource:
    1. Create a method named "DelegatingResourceDescription getRepresentationDescription(Representation rep)"
    2. Switch on the "rep" argument (or use if/else)
    3. Create a DelegatingResourceDescription according to the rep, using addProperty for the properties that you need
    4. Tip: Use description.addProperty("auditInfo", findMethod("getAuditInfo")) for not creator/dateCreated/changedBy/dateChanged properties
    5. Tip2: the MetaDataDelegatingCrudResource class defines the "ref" representation for you. 
  5. DO NOT add locationId to the getRepresentationDescription method. That is an internal number that should never be exposed over web services
  6. Adding a new property (fullAddress) that is not on the Location object (only done here as an example.  Patient.name is a better example)
    1. There is no Location.getFullAddress() method, so automatic translation of this into json/xml will fail in the webservices module.
    2. Add description.addProperty("fullAddress", findMethod("getFullAddress")) to the getRepresentationDescription method
    3. Add a method SimpleObject getFullAddress(Location location) on the LocationResource class.
      1. This method is called anytime a user requests to see the "fullAddress" property in the json/xml
    4. The implementation of the method can be anything using the Location object.  Something like:
      1. return location.getAddress1() + " " + location.getAddress2() + " " + location.getCityVillage() + " " + location.getStateProvince()
  7. Add a newDelegate() method
    1. This is used by the parent class to know how to construct our object (our delegate)
  8. Add a save(Location location) method
    1. This is used by the parent class to know how to persist our object to the database.  This is typically just Context.getSomeService().saveMyObject(object)
  9. Add a getByUniqueId(String s) method
    1. The parent class calls this for all getters.  You should look up your object by uuid. If your object can also be looked up by a unique name, you can do that in this method as well as the uuid.
    2. This method is what allows your object to be a spring "Converter".  So other WS methods can refer to your object by uuid/name as well
    3. DO NOT look up by primary key.  Primary keys should not exposed over web services
  10. Add a purge(Location location, RequestContext context) method
    1. You can get the reason (if needed) out of the request context
  11. Add a doGetAll(RequestContext context)
    1. This should return a list of every location objects that is still valid (not retired)
    2. The context object has parameters like "limit", "maxresults", "start", etc
  12. Add doSearch(String query, RequestContext context)
    1. This should return a list of location objects with a fuzzy search on the query. 
    2. The context object has parameters like "limit", "maxresults", "start", etc
    3. There is a helper class named ServiceSearcher that you can use to help with the paging, index, etc
  13. If you have a non-standard setter method:
    1. TODO
  14. Sub resources (like patient name)
    1. TODO

...