Skip to content

MV-GH/LemmyBackwardsCompatibleAPI

Repository files navigation

Sonatype Nexus (Snapshots) badge badge badge badge badge badge badge badge badge example workflow License: AGPL v3 GitHub stars

LemmyBackwardsCompatibleAPI

A backwards compatible API for Lemmy made with Kotlin Multiplatform. Supports Lemmy 0.18+

Usage

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>()

Installation

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") }

Goals

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.

Backwards Compatibility Strategy

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:
  • 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.

AutoGenerated Code

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 dukat
  • GenRoutes: This script generates templates for the routes, LemmyApiService and its implementation. It will output it to temp/ and you can copy what you need. It does this by extracting the routes from lemmy_openapi_spec
  • GenMapperRoutes: 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 Interface MapperGenerator. 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 with GenMapperRoutes. This will output them to the temp/ 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.

Extra features

  • JVM datatypes implement Serializable
  • Android datatypes implement Parcelable and Serializable