A backwards compatible API for Lemmy made with Kotlin Multiplatform. Supports Lemmy 0.18+
val api = LemmyApi.getLemmyApi("voyager.lemmy.ml", auth)
api.getSite()
// Some features are version dependent, so we can check if they are supported
if(api.FF.instanceBlock()) {
api.instanceBlock()
}
// These enums can be different depending on the version of the API
api.getSupportedEntries<SortType>()
implementation("it.vercruysse.lemmyapi:lemmy-api:VERSION")
It is currently in beta, so only snapshots are available.
Add the following repository
maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots") }
The intention is to provide an easy-to-use API that supports a wide range of Lemmy instances. The backwards compatibility is achieved by transforming the requests and responses to a "universal" type. And by allowing you to check if a feature is supported by the instance. That way you can change the behavior of your app depending on the instance's version.
It is a non-goal to provide a stable API. The API can change with every iteration without warning nor deprecation.
The API is backwards compatible by using the following strategy:
- API route gets added. Add a function that returns if this feature is supported. Older versions implement this route by throwing an error (nonSupported).
- API route gets removed.
newer versions implement this route by throwing an error (nonSupported).
Is added to the
oldRoutes
interface - API routes its request/response changes.
For this, we transform response/requests to a "universal" type.
Concrete this means, it will usually be the modified latest datatypes.
So that the response will be the same regardless of which version.
Here are some examples from how this will look concrete:
- Move admin flag from person to local_user, pre 0.19 version APIs will map their datatype to the latest datatype by moving that field from person to local_user
- ... TODO: add more examples
- Enum entries keep an added/removed version.
Using get
getSupportedEntries<Type>
we can retrieve the supported entries for a given enum. This is useful, for example, for sorting, where the sorting options can change between versions.
To minimize the maintenance burden, many aspects have been automated.
This is done through kotlinscripts which are located in the GeneratorScripts
submodule
There is 3 main scripts:
GenTypes
: This script updates the datatypes for the set package version (ex: v0x19). It does this by downloading the TS types from lemmy-js-client. And applying the transformations (see here) to the types. This script does require that you have downloaded dukatGenRoutes
: This script generates templates for the routes, LemmyApiService and its implementation. It will output it totemp/
and you can copy what you need. It does this by extracting the routes from lemmy_openapi_specGenMapperRoutes
: This script is a bit more complex. To prevent having to manually write all the basic transformations between datatypes of different versions. We can automatically generate them with Konvert. This is done by having a definition file, in this case it is just a InterfaceMapperGenerator
. Uncomment the annotations and build the project. The mappings will be generated in the build folder. Then you can copy them to the appropriate Transformer class. Now to prevent having to manually write the definition file, we can generate it withGenMapperRoutes
. This will output them to thetemp/
folder. And these are generated by comparing the datatypes from the given source package version and the given target package version. Datatypes, which exist in both, will have a mapping generated.
- JVM datatypes implement
Serializable
- Android datatypes implement
Parcelable
andSerializable