lichess-org / api

Lichess API documentation and examples

Home Page:https://lichess.org/api

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Doc response samples and API mismatch

PesiTheWizard opened this issue · comments

The above used a bot:play token

Thanks for reporting these inconsistencies. Fixed (1) and (4). soketVersion from (1) serves no purpose in the public API for now, so I think it's fine to omit.

commented

There's more. For example, a 200 response to /api/stream/event is defined as

api/doc/specs/lichess-api.yaml

Lines 5140 to 5145 in d14ec92

oneOf:
- $ref: '#/components/schemas/GameStartEvent'
- $ref: '#/components/schemas/GameFinishEvent'
- $ref: '#/components/schemas/ChallengeEvent'
- $ref: '#/components/schemas/ChallengeCanceledEvent'
- $ref: '#/components/schemas/ChallengeDeclinedEvent'

Picking one, GameStartEvent is described as

api/doc/specs/lichess-api.yaml

Lines 10346 to 10353 in d14ec92

GameStartEvent:
type: object
properties:
type:
type: string
const: gameStart
game:
$ref: '#/components/schemas/GameEventInfo'

which contains a GameEventInfo, which in turn is described as

api/doc/specs/lichess-api.yaml

Lines 10307 to 10344 in d14ec92

GameEventInfo:
type: object
properties:
id:
type: string
source:
type: string
enum:
- lobby
- friend
- ai
- api
- tournament
- position
- import
- importlive
- simul
- relay
- pool
- swiss
status:
type: object
properties:
id:
type: integer
enum: [10, 20, 25, 30, 31, 32, 33, 34, 35, 36, 37, 38, 60]
name:
$ref: '#/components/schemas/GameStatus'
winner:
type: string
enum: [white, black]
compat:
type: object
properties:
bot:
type: boolean
board:
type: boolean

However, looking at the gameStart example from here

api/doc/specs/lichess-api.yaml

Lines 5153 to 5154 in d14ec92

gameStart:
$ref: '#/components/examples/gameStart'

one discovers there are a lot more undocumented fields possibly returned by the API, for which the definition isn't know:

api/doc/specs/lichess-api.yaml

Lines 10888 to 10913 in d14ec92

gameStart:
value: {
"type":"gameStart",
"game": {
"gameId": "rCRw1AuO",
"fullId": "rCRw1AuOvonq",
"color": "black",
"fen": "r1bqkbnr/pppp2pp/2n1pp2/8/8/3PP3/PPPB1PPP/RN1QKBNR w KQkq - 2 4",
"hasMoved": true,
"isMyTurn": false,
"lastMove": "b8c6",
"opponent": { "id": "philippe", "rating": 1790, "username": "Philippe" },
"perf": "correspondence",
"rated": true,
"secondsLeft": 1209600,
"source": "friend",
"status": { "id": 20, "name": "started" },
"speed": "correspondence",
"variant": { "key": "standard", "name": "Standard" },
"compat": {
"bot": false,
"board": true
},
"id": "rCRw1AuO"
}
}

In addition, it's hard or impossible to discern when fields are nullable. Unfortunately these issues make it really hard to write a consistent client, and pretty much impossible to generate one with OpenAPI Generator. Is there a place in (presumably) the lila repository where more reliable information can be found for the moment?


Edit:

Also, the example structure isn't even correct: Here's a real json object received from the API. The compat field isn't part of the challenge object, unlike in the example:

{
  "challenge": {
    "challenger": {    ...    },
    "color": "random",
    "destUser": {    ...    },
    "finalColor": "black",
    "id": "GqB3EN2W",
    "perf": {    ...    },
    "rated": false,
    "speed": "blitz",
    "status": "created",
    "timeControl": {    ...    },
    "url": "https://lichess.org/GqB3EN2W",
    "variant": {    ...    }
  },
  "compat": {
    "board": true,
    "bot": true
  },
  "type": "challenge"
}

Here's the example for a challenge:

api/doc/specs/lichess-api.yaml

Lines 10734 to 10783 in d14ec92

examples:
challenge:
value: {
"type":"challenge",
"challenge": {
"id":"7pGLxJ4F",
"url": "https://lichess.org/VU0nyvsW",
"status":"created",
"compat": {
"bot": false,
"board": true
},
"challenger": {
"id":"lovlas",
"name":"Lovlas",
"title":"IM",
"rating": 2506,
"patron": true,
"online": true,
"lag": 24
},
"destUser": {
"id":"thibot",
"name":"thibot",
"rating": 1500,
"provisional": true,
"online": true,
"lag": 45
},
"variant": {
"key":"standard",
"name":"Standard",
"short":"Std"
},
"rated": true,
"timeControl": {
"type":"clock",
"limit": 300,
"increment": 25,
"show":"5+25"
},
"color":"random",
"finalColor": "white",
"speed":"rapid",
"perf": {
"icon":"#",
"name":"Rapid"
}
}
}

Yes, the lila repository contains the real definitions. In many cases, there is a JsonView class/file which handles the serialization. For the events stream, it's done here: https://github.com/lichess-org/lila/blob/master/modules/api/src/main/EventStream.scala.

You are very welcome to contribute PRs to improve the specification. Having it accurate and complete enough to allow automatic client generation has been discussed a bit here and there and definitely would be really cool but so far nobody has had the time and interest to make major improvements in this area.

commented

@benediktwerner Yeah, I got to EventStream.scala yesterday also. I think the very manual way json is generated in lila is problematic for accurate documentation. To achieve accurate documentation, I think generating the API should be preferred, however, it looks like a massive effort. Just for describing the object schemas, you'd probably have to lift every returned json type into it's own data class, and annotate accordingly. When working in Spring, you can then annotate each rest method accordingly to generate an accurate API while generating the json from the data classes with Swagger.

In general, I think investing effort into automatic generation is worthwhile because it saves a lot of work and trouble in the long term.

It might be something I can contribute to, though I'm not versed in Scala at all unfortunately.

commented

Hey all any reason why task 3 is not finished?

commented

I can work on this