FHIR Chat · Common attributes across resources · hapi

Stream: hapi

Topic: Common attributes across resources


view this post on Zulip James Agnew (May 12 2016 at 14:20):

Hi All, so a proposal came to me from @Bryn Rhodes via @Grahame Grieve:

There's actually a common set of elements across all resources - identifier, code, url, date, etc
If we make every resource implement that interface, and then we can generate the accessors for each resource, based on meta data defined in the resource definitions (I have a slot for that)

My immediate reaction is that this could be convenient, but would also be problematic. My main concern is that you lose some of the benefit of static type checking. E.g. if Patient now has a method getCode() even though the patient resource has no such property, I might accidentally call patient.getCode() and I'm presumably now getting a runtime error instead of a compile time one.

One possible mitigation of this would be to split the proposal into a few interfaces. IHasCode, IHasIdentifier etc, and have the individual resources implement those. Another option might be to deprecate the methods on the resources that aren't used.

Thoughts?

(Pinging @Ewout Kramer @Brian Postlethwaite for their thoughts from the .NET side)

view this post on Zulip Grahame Grieve (May 12 2016 at 15:24):

my immediate response is that IHasCode is just moving the deck chairs around. Yes, this will create run time errors. But this is mainly useful when you have a object of type "Resource" anyway, and wahtever you do is going to be run-time error anyway

view this post on Zulip Grahame Grieve (May 12 2016 at 15:24):

if thing instanceof [type] then ...
else
runtime error....

view this post on Zulip Grahame Grieve (May 12 2016 at 15:25):

so I don't think that's persausive

view this post on Zulip Michael Lawley (May 12 2016 at 19:18):

I would certainly help implementers of Terminology Services where all our key Resources have common elements.
FWIW, my first thought for mitigating the issue of unwanted methods on other Resources was also your suggestion of marking them as deprecated. Reasonable, I think, from a Java perspective, but would this need to flow across into all language bindings?

view this post on Zulip Grahame Grieve (May 12 2016 at 20:18):

I don't follow the deprecation argument, So you deprecate the implementation - so what

view this post on Zulip James Agnew (May 12 2016 at 20:48):

The idea there is that if you are putting getCode() on the Resource class, you could put a copy of it on Patient that is marked as deprecated so that users get a compile-time warning if they try to use it on Patient.

The more I think about it though, I'm not clear on what problem this solves. Does this method throw an exception if you call it incorrectly? (say, getCode() on Patient) If so, you need to test for instanceof before you call it anyhow so you could cast it then...

view this post on Zulip Grahame Grieve (May 12 2016 at 20:52):

ok you want a deprecation so as not to use it directly - I follow that

view this post on Zulip Grahame Grieve (May 12 2016 at 20:53):

I would return null - there is no code on patient. Since the intent is that you use it generically, it's not an error to call it on patient, there just isn't one.

view this post on Zulip James Agnew (May 12 2016 at 20:56):

Ugh, I don't like that at all... That's a recipe for bugs. I guess this is my general problem with this, the whole intent we have with HAPI at least is to provide as much compile-time checking as possible for code. That's why we use annotated fields for extensions for instance.

Would it make more sense to just provide a utility class with a method List<CodeableConcept> getCode(Resource theResource);

view this post on Zulip Grahame Grieve (May 12 2016 at 20:56):

you can't have an implementation with a lower visibility can you?

view this post on Zulip James Agnew (May 12 2016 at 20:56):

sadly not

view this post on Zulip Grahame Grieve (May 12 2016 at 20:56):

really, I don't understand why that's better than just putting it on an interface

view this post on Zulip Grahame Grieve (May 12 2016 at 20:57):

what's the practical difference between resource.getCode() and Utilities.getCode(resource) other than ungainly syntax?

view this post on Zulip James Agnew (May 12 2016 at 21:02):

well, to me the practical difference is that there are no misleading methods showing up in intellisense on Patient.java this way. If I use the utility method it's clear that I need to be careful.

To be honest though, I still don't understand why this whole thing is useful. What are the situations where you don't care what type of resource you have, you just want its code or identifier. Are they common enough that they merit "polluting" the resource hierarchy for convenience? That's what I'm trying to weigh...

view this post on Zulip Grahame Grieve (May 12 2016 at 21:04):

common properties on the conformance resource - which will be spreading to more CQI resources. Identifier. .... perhaps status.... And a bunch of things that are a datatype ModelMetaData that will be flattened on the various resources it lives on

view this post on Zulip Grahame Grieve (May 12 2016 at 21:05):

I constantly use .getUrl(), .getStatus(), .getDate(), .getName() on conformance resources generically

view this post on Zulip Grahame Grieve (May 12 2016 at 21:05):

Bryn does too

view this post on Zulip Grahame Grieve (May 12 2016 at 21:07):

I would not put .getCode on there - this is not something that is remotely consistent across resources

view this post on Zulip James Agnew (May 12 2016 at 21:09):

On a related note, I've heard complaints now from a few developers that the DSTU3 structures have pages and pages of "castToFoo" methods showing up in intellisense. I do see value in being kind to people who work that way..

But surely we wouldn't add something like getUrl() to Resource just for your/Bryn's conformance use cases? If a bunch of the conformance resources all have these properties, should we just have a BaseConformanceResorce class that all of them inherit from that adds the 4 properties you list?

view this post on Zulip Grahame Grieve (May 12 2016 at 21:21):

well, maybe we could, yes, though I'm not sure where I'd drive it from.

view this post on Zulip Grahame Grieve (May 12 2016 at 21:22):

can we do something clever with the cast* methods, or is it all or nothing?

view this post on Zulip Josh Mandel (May 12 2016 at 21:36):

I'm kind of worried that we're inventing a whole alternative approach to inheritance with this interfacey-view-layer thing.

view this post on Zulip Grahame Grieve (May 12 2016 at 21:37):

well, we are extremely limited in our approach to inheritence. Further, we often do not use it because not all features of an element are common, even when the parts related to code generation are constant

view this post on Zulip Grahame Grieve (May 12 2016 at 21:38):

but i suppose that rather than interfaces, I could optimise the generation to use inheritence carefully

view this post on Zulip Grahame Grieve (May 12 2016 at 21:38):

James, how would you feel about introducing a new abstract resource "ConformanceResource"

view this post on Zulip James Agnew (May 12 2016 at 21:39):

I would feel very good about that approach

view this post on Zulip Josh Mandel (May 12 2016 at 21:39):

:-)

view this post on Zulip Grahame Grieve (May 12 2016 at 21:40):

@Bryn Rhodes - I think that this comes to the same outcome, and I think it works for you

view this post on Zulip Grahame Grieve (May 12 2016 at 21:42):

James, the getXType methods - I use these a lot so I love them but I know that they clutter the hints

view this post on Zulip James Agnew (May 12 2016 at 21:43):

Yeah, I understand that... I don't see an easy solution to that, and at least they are grouped together.

view this post on Zulip Grahame Grieve (May 12 2016 at 21:45):

can't see any way to suppress them

view this post on Zulip James Agnew (May 12 2016 at 21:46):

I'd say let's leave them alone then.

view this post on Zulip Bryn Rhodes (May 12 2016 at 22:05):

So are we saying that there would be a BaseConformanceResource type that all the conformance and artifact-related resources would descend from, and we would flatten the ModuleMetadata type into elements on that resource?

view this post on Zulip Grahame Grieve (May 12 2016 at 22:06):

maybe. Or another base resource instead - depending on how the resources are changed

view this post on Zulip Bryn Rhodes (May 12 2016 at 22:08):

That makes sense and addresses the use case.

view this post on Zulip Grahame Grieve (May 12 2016 at 22:22):

ok. I'll do that. james, do you need to do something in HAPI if I do that?

view this post on Zulip James Agnew (May 12 2016 at 22:26):

Nope, just let me know when it's ready and I'll sync the structures into HAPI

view this post on Zulip Grahame Grieve (May 12 2016 at 22:29):

ok I'll let you know

view this post on Zulip Brian Postlethwaite (May 13 2016 at 04:08):

On the IHasCode interface stuff, my 2c is that there are probably a couple of groups of resources that could have a common interface like that IConformanceResource (with the URL etc params), IPatientRelatedResource (with patient, identifiers ...)

view this post on Zulip Grahame Grieve (May 13 2016 at 07:57):

that's what we decided to do

view this post on Zulip Grahame Grieve (May 13 2016 at 07:58):

@Ewout Kramer @Brian Postlethwaite would you do the same in C# if I defined the semantics in a mapping in the structure definition?

view this post on Zulip Brian Postlethwaite (May 13 2016 at 12:30):

Do you mean generate the baseconformance resource?

view this post on Zulip Grahame Grieve (May 13 2016 at 12:31):

yes.

view this post on Zulip Brian Postlethwaite (May 13 2016 at 12:32):

If so then yes could do that

view this post on Zulip Brian Postlethwaite (May 13 2016 at 12:32):

Ok.

view this post on Zulip Grahame Grieve (May 13 2016 at 12:32):

great.

view this post on Zulip Brian Postlethwaite (May 13 2016 at 12:37):

With dot net we'd use extension methods for the little used stuff in a special namespace for those that want them.
This reduces stuff in intelligence. Don't know if there is an equivalent in java

view this post on Zulip James Agnew (May 13 2016 at 23:15):

nope :(


Last updated: Apr 12 2022 at 19:14 UTC