When I started out implementing services in webMethods Integration Server, I didn’t really know how to structure my packages. I lacked the experience in what should go where and which resources are best grouped together. So I ended up with a different folder structure for all my packages. At this point, finding the resource I wanted to edit was very cumbersome.
So I asked a Software AG consultant for his recommendation regarding the folder structure of my packages. And this is what we came up with:
I’ve used this structure for quite some time now and I’m pretty happy with it so far. Let me go into the details on the different folders.
The root folder should be named exactly like the package (hence
PackageTemplate). Although this might seem like redundancy, you need to be aware of the fact, that the package name is not part of the service namespace! To be able to uniquely identify a service, you need some kind of fully qualified name. And the package name is not part of that. So it’s best practice to create a folder with the same name as the package as the root folder for the package contents. You can then qualify a service like this:
Documents represent the package’s public API, i.e. the resources that are publicly available to every other package and every external consumer. Think of them like
public attributes and methods in Java. This API needs to be stable, because changing it is expensive and error-prone. Once you publish a service, you’ll never know who calls it. Therefore, changing the interface later may lead to errors in the consumers.
Internal contains the private API of the package. This API can be modified as you like, because there are no external dependencies on it. Think of the services and documents in their respective subfolders als
private methods and attributes in Java. You can hide the internals of your package by putting them in this structure.
This does not mean, that other packages or consumers are not able to use these resources. They are not technically hidden from the outside. It’s merely a convention that every package has to follow and every developer needs to respect (and every architect needs to enforce 😉 ).
Webservices and REST Resources
Webservices (SOAP and REST) form an additional layer on top of a package’s documents and services. They only provide another way of accessing the resources through common interfaces. And they might look quite different from the underlying services (e.g. a
POST-Method might get translated to a simple service call) and follow their own lifecycle. Therefore, they should be put into their own folders.
Webservices contains only Web Service Descriptors and all REST Resources and their services (
_get etc.) are put into
Schemas and Triggers
Triggers contain their respective resources. Schemas can define the data structures for multiple services and Triggers implement asynchronous sequences. These resources play a central role in many packages and need to be taken care of separately.
Adapters contains the package’s different adapter services. For example, in our case there are adapter services for EntireX, JDBC and .NET. And they are all quite different from your Flow services, as they need additional Integration Server adapters installed and integrate external systems into Integration Server. It’s useful to separate those special services from your own.
What best practices do you follow when structuring your Integration Server packages? Do you have anything to add to my list?
6 thoughts on “Best practices for structuring packages in webMethods Integration Server”
Services folder can further split into Flow and Java sub-folders.
thanks for the comment. However, I would not add subfolders to the
Servicesfolder, because they become part of the services’ namespace, e.g.
MyPackage.Services.Java.MyService. I don’t think the outside world should know or care about implementation details like the language. But of course I see your point because it makes for a cleaner separation of the two different service types. Perhaps I would use the subfolders underneath the private API where nobody “sees” the structure.
You can also add the below folders:
specifications (for input and output)
utils (for having utility services specific to this package). If you have a generic utility package then it is not required.
schedulers ( if you have any scheduler services)
thank you for your comment. I’m sure your additions are useful. I didn’t think of them, because we (currently) don’t use specifications and schedulers.
The aspect of naming your root folder and the package the same stems from the early days of Integration Server and the “Developer”. You couldn’t view the associated package for a given service however, since the introduction of the “Designer” this is no longer true. SOA has evolved since then and now a namespace taxonomy and nomenclature compatible with organisation and purpose might be more appropriate. Consider a package naming convention of <scope>, then instead of the package to the same as a root folder, consider mapping it to a hierarchal folder structure of …<scope><version> and then the folder structure espoused in your blog. This allows for multiple packages with different content and purpose to layer into the folder structure that supports the SOA taxonomy of the org and has additional benefits of granular ACL configuration, multiple teams working in the same capability etc especially useful with globally distributed teams working on a common code base.
SOA artefacts can then be found using the taxonomy and this can be mirrored within the governance tools of choice.
The downside is more packages, more thought at design time and greater granularity for the developer to work with. It will not impact the performance other than the IS startup but it will allow finer tuning of the production environment allowing application partitioning based on the classification within the taxonomy.
Food for thought….
thanks for the explanation and the naming suggestion. The only thing I don’t like about your idea is the version in the folder structure. I try to not version my APIs at all. However, if you need to maintain different versions for older clients that would be a better way than to add another package with the new version in its name.