Thread: Public vs internal APIs
Hi, I'm looking into implementing java.sql.Struct in the jdbc driver, and it turns out I do not like PGObject for various reasons. E.g. it cannot "append itself to a buffer", it ties decoding with PGObject itself. I'm going to try another approach, however I would like to avoid leaking that API to the public API of the driver. Having said that, I wonder what if we add: @ExperimentalAPI, @PublicAPI, @InternalAPI kind of annotations, so we can clearly mark internal classes as, well, internal so our clients would not accidentally depend on the internal classes? Java does not yet allow to define "published API" (see [1]), so it would be nice to mark some APIs as internal. For instance it makes sense marking the following classes as @InternalAPI: org.postgresql.util.LruCache org.postgresql.core.Parser etc [1]: http://martinfowler.com/ieeeSoftware/published.pdf -- Regards, Vladimir Sitnikov
Actually I would be a friend of instead restructuring the package hierarchy, as this is was it was invented for originally.;-) -----Original Message----- From: pgsql-jdbc-owner@postgresql.org [mailto:pgsql-jdbc-owner@postgresql.org] On Behalf Of Vladimir Sitnikov Sent: Donnerstag, 23. Juli 2015 17:33 To: List Subject: [JDBC] Public vs internal APIs Hi, I'm looking into implementing java.sql.Struct in the jdbc driver, and it turns out I do not like PGObject for various reasons. E.g. it cannot "append itself to a buffer", it ties decoding with PGObject itself. I'm going to try another approach, however I would like to avoid leaking that API to the public API of the driver. Having said that, I wonder what if we add: @ExperimentalAPI, @PublicAPI, @InternalAPI kind of annotations, so we can clearlymark internal classes as, well, internal so our clients would not accidentally depend on the internal classes? Java does not yet allow to define "published API" (see [1]), so it would be nice to mark some APIs as internal. For instance it makes sense marking the following classes as @InternalAPI: org.postgresql.util.LruCache org.postgresql.core.Parser etc [1]: http://martinfowler.com/ieeeSoftware/published.pdf -- Regards, Vladimir Sitnikov -- Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-jdbc
> instead restructuring the package hierarchy, as this is was it was invented for originally. package-private is not enough. Java9 will have modules for that, however we would have to live with java8 for a while. Which package would you suggest for org.postgresql.util.LruCache? Vladimir
Actually I would go with a really flat structure, so we can simply use "default" and "public" visibility of classes to distinguishbetween API and implementation. If more structure is wanted, we could use "org.postgresql" vs. "org.postgresql.internal"to make it more clear which classes are private and which are published. Unfortunately Java has no "friends" declaration. :-( -----Original Message----- From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] Sent: Donnerstag, 23. Juli 2015 18:35 To: Markus KARG Cc: List Subject: Re: [JDBC] Public vs internal APIs > instead restructuring the package hierarchy, as this is was it was invented for originally. package-private is not enough. Java9 will have modules for that, however we would have to live with java8 for a while. Which package would you suggest for org.postgresql.util.LruCache? Vladimir
Any hint to the project that successfully uses "all stuff in a single java package" approach? I'm afraid that is too tight. For instance, RxJava mixes "annotations and internal package" approach: https://github.com/ReactiveX/RxJava#versioning Vladimir
Well, yes, I also don't think that it would work well in the long term. But we could go with the ".internal" subpackage forexample. On the other hand I wonder wether the risk of using internal stuff really exists. I mean, people shall code against java.*API, not against org.postgresql implementation. If we make this clear in the JavaDocs, maybe it is enough? -----Original Message----- From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] Sent: Donnerstag, 23. Juli 2015 19:12 To: Markus KARG Cc: List Subject: Re: [JDBC] Public vs internal APIs Any hint to the project that successfully uses "all stuff in a single java package" approach? I'm afraid that is too tight. For instance, RxJava mixes "annotations and internal package" approach: https://github.com/ReactiveX/RxJava#versioning Vladimir
>I mean, people shall code against java.* API, not against org.postgresql implementation. If we make this clear in the JavaDocs,maybe it is enough? On contrary, we do want to expose advanced stuff PostgreSQL has. For instance: "timestamp with time zone". Not everybody can upgrade to java 8. Another example is COPY command: JDBC has no standard way of doing that. We have to define org.postgresql interface for it. JDBC is not that good for async operations either: logical decoding, notify, etc, so again some org.postgresql might do much better job here. For regular stuff like "send int here and there", everybody should use regular JDBC, however, there are cases when non-JDBC usage is intended. Vladimir
Understood. But how big is the risk those people that do not go with pure JDBC but choose to go with native PostgreSQL driverclass are not clever enough to abstain from picking implementation details? And how problematic is it, when they actuallyuse those classes? BTW, in the long term would be a good idea to contribute the needed changes to JDBC by becoming an official JSR EG member. Dave already applied AFAIK. -----Original Message----- From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] Sent: Donnerstag, 23. Juli 2015 20:11 To: Markus KARG Cc: List Subject: Re: [JDBC] Public vs internal APIs >I mean, people shall code against java.* API, not against org.postgresql implementation. If we make this clear in the JavaDocs,maybe it is enough? On contrary, we do want to expose advanced stuff PostgreSQL has. For instance: "timestamp with time zone". Not everybody can upgrade to java 8. Another example is COPY command: JDBC has no standard way of doing that. We have to define org.postgresql interface for it. JDBC is not that good for async operations either: logical decoding, notify, etc, so again some org.postgresql might do muchbetter job here. For regular stuff like "send int here and there", everybody should use regular JDBC, however, there are cases when non-JDBCusage is intended. Vladimir