2009 Implementers Group Meeting Program How to use the API
Services Overview
3 layer architecture
- DB layer
- Data access layer (Hibernate)
- Services
- Patient
- User
- Obs
- (10-15 svcs)
Abstraction
Hibernate abstracts the implementation - do not need to code to the db. Map getters and setters to table fields
Each services has a DAO dedicated to it.
- Examples:
- UserDAO
- PatientDAO
- Typical DAO Methods:
- Save
- Get
- Delete
The service methods are more complex
Class Organization
OpenMRS API jar has the services, DAO's.
Web API jar has only the controllers needed for the web app.
- When you write a module you need to access items from Web API.
- 90% of the time you don't need to use the Web API; instead, you'll be accessing methods from the OpenMRs API.
If you are starting your own module, you may reference the objects already in the OpenMRS API. But if your module refers to its own objects, you need your own dao's and hibernate mapping module
Tips for Build.xml
- package-all - creates openmrs-api, wenapi, and test api jars
- test api jar packages the helper classes/objects to make tests easier
Examples
Services are in org.openmrs.api package.
UserService has basic methods that act on simple openmrs objects, as opposed to table columns. UserServiceImpl is its implementation.
Controllers are where access of services happens.
UserFormController
- Example creating a user and persisting: call the api method for that object - Object.Save
- Takes 2 params - the object and a passsword string (for the user). If we're updating it can be null.
- Usually save methods do not take more than one object - this is not a typical case.
public List<User> getListofUsers() { UserService userService = Context.getUserService; Role role = userService.getRole("provider"); List<User> users = userService.getUsersInRole("provider"); return users; }
Spring injects the specific implementation into the service (such as UserService) at startup.
In openmrs-trunk, applicationContext-service.xml has the setup config for Spring.
<bean id="context" class="org.openmrs.api.context.Context"> <property name="serviceContext"><ref bean="serviceContext"/></property> <property name="contextDAO"><ref bean="contextDAO"/></property> </bean>
This bean called BasicModuleFormController is of type BasicModuleFormController. Spring at startup instantiates this class, calls this setter, and passes its associated string
If you want to create a service, start from the module start page at http://modules.openmrs.org/modules/ - see the Example code - http://dev.openmrs.org/browser/openmrs-modules - to copy/paste code snippets. On modules wiki page at http://openmrs.org/wiki/Modules, see the Overall Module Structure listing.
Calling the moduleService.
SessionFactory - used by Hibernate
Demo of creating a module
_ Code examples are incomplete and probably quite wrong... _
Best practice: Extend BaseOpenmrsService in order to get the onStartup and shurdown in case something is added to BaseOpenmrsService .
public interface BasicModuleService extends BaseOpenmrsService { // copy the class and package from the xml definition private Log log = LogFactory.getLog(this.getClass()); public void onStartup // flip back to the applicationContext.xml and see what else we demand to have public void setExampleField(ClassInApplicationContext) { // TODO } public List<>Users getUsers (String role) { if () { return this.dao... } }
Must implement the DAO method.
Best practice: Return should be an interface.
Creating the interface for the DAO
public interface BuildModuleDAO // going back to applicationContext.xml - setter is specified. public class HibernateBuildModule implements ModuleDAO { private SessionFacory sessionFactory = null; public void setSessionFactory sf () { this.sessionfactory = sf; } public List<User> getUser (String role, Object obj, Object obj2, Object obj Criteria criteria - sessionFacotry.getCurrentService().createCriteria(); criteria.addExpression.eq("roles",''); criteria.addRestrictions.isNotNull("username"); // allows this object to be reused across different service methods if (obj != null) { criteria...... return criteria list(); }
Criteria in hibernate is a way to build sql objects in hibernate - user Java objects
Opened up the controller
The service upon startup is in the Context. Address it thusly:
BasicModuleService myService = (BasicModuleService) Context.getService(BasicModuleService.class); List<User> = myService.getMyFancyListbyRole("provider");
Should not cache this service - if it's unloaded and reloaded - length of the object is the length of time of the module. Service itself may cache things. When reloaded the cache is cleared up.
AOP
Allows your module to affect the services of another module or of core.
"Anytime a Person method is called, call my method"
AOP only works on the entire class.
Your service will be called on every get, delete, etc.
3 different types of AOP
- Before service
- After
- Around (before and after)
If you are doing an around advice, use the matches method
OpenMRS Docs
Best place to find a list of methods - attach source to your project.(Demo on how to do this in Eclipse. Browse to attach source)
Javadocs are at doc.openmrs.org.