Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Commands API version 1 #4118

Merged
merged 18 commits into from
Jan 5, 2024
Merged

Commands API version 1 #4118

merged 18 commits into from
Jan 5, 2024

Conversation

badlop
Copy link
Member

@badlop badlop commented Dec 1, 2023

This PR includes many improvements in API versioning, mod_http_api, ejabberdctl, and some commands.

Support for API Versioning

Until now, when a new ejabberd release changed some API command (an argument renamed, a result in a different format...), then you had to update your API client to the new API at the same time that you updated ejabberd.

Now the ejabberd API commands can have different versions, by default the most recent one is used, and the API client can specify the API version it supports.

In fact, this feature was implemented seven years ago, included in ejabberd 16.04, documented in ejabberd Docs: API Versioning... but it was never actually used!

This ejabberd release includes many fixes to get API versioning up to date, and it starts being used by several commands.

Let's say that ejabberd 23.10 implemented API version 0, and this ejabberd xx.yy adds API version 1. You may want to update your API client to use the new API version 1... or you can continue using API version 0 and delay API update a few weeks or months.

To continue using API version 0:

  • if using ejabberdctl, use the switch --version 0. For example: ejabberdctl --version 0 get_roster admin localhost
  • if using mod_http_api, in ejabberd configuration file add v0 to the request_handlers path. For example: /api/v0: mod_http_api

Check the details in ejabberd Docs: API Versioning.

ejabberd Commands API Version 1

When you want to update your API client to support ejabberd API version 1, those are the changes to take into account:

  • Commands with list arguments
  • mod_http_api does not name integer and string results
  • ejabberdctl with list arguments
  • ejabberdctl list results

All those changes are described in the next sections.

Commands with list arguments

Several commands now use list argument instead of a string with separators (different commands used different separators: ; : \\n ,).

The commands improved in API version 1:

For example, srg_create in API version 0 took as arguments:

{"group": "group3",
 "host": "myserver.com",
 "label": "Group3",
 "description": "Third group",
 "display": "group1\\ngroup2"}

now in API version 1 the command expects as arguments:

{"group": "group3",
 "host": "myserver.com",
 "label": "Group3",
 "description": "Third group",
 "display": ["group1", "group2"]}

mod_http_api not named results

There was an incoherence in mod_http_api results when they were integer/string and when they were list/tuple/rescode...: the result contained the name, for example:

$ curl -k -X POST -H "Content-type: application/json" -d '{}' "http://localhost:5280/api/get_loglevel/v0"
{"levelatom":"info"}

Staring in API version 1, when result is an integer or a string, it will not contain the result name. This is now coherent with the other result formats (list, tuple, ...) which don't contain the result name either.

Some examples with API version 0 and API version 1:

$ curl -k -X POST -H "Content-type: application/json" -d '{}' "http://localhost:5280/api/get_loglevel/v0"
{"levelatom":"info"}

$ curl -k -X POST -H "Content-type: application/json" -d '{}' "http://localhost:5280/api/get_loglevel"
"info"

$ curl -k -X POST -H "Content-type: application/json" -d '{"name": "registeredusers"}' "http://localhost:5280/api/stats/v0"
{"stat":2}

$ curl -k -X POST -H "Content-type: application/json" -d '{"name": "registeredusers"}' "http://localhost:5280/api/stats"
2

$ curl -k -X POST -H "Content-type: application/json" -d '{"host": "localhost"}' "http://localhost:5280/api/registered_users/v0"
["admin","user1"]

$ curl -k -X POST -H "Content-type: application/json" -d '{"host": "localhost"}' "http://localhost:5280/api/registered_users"
["admin","user1"]

ejabberdctl with list arguments

ejabberdctl now supports list and tuple arguments, like mod_http_api and ejabberd_xmlrpc. This allows ejabberdctl to execute all the existing commands, even some that were impossible until now like create_room_with_opts and set_vcard2_multi.

List elements are separated with , and tuple elements are separated with :.

Relevant commands:

Some example uses:

ejabberdctl add_rosteritem user1 localhost testuser7 localhost NickUser77l gr1,gr2,gr3 both
ejabberdctl create_room_with_opts room1 conference.localhost localhost public:false,persistent:true
ejabberdctl subscribe_room_many user1@localhost:User1,admin@localhost:Admin room1@conference.localhost urn:xmpp:mucsub:nodes:messages,u

ejabberdctl list results

Until now, ejabberdctl returned list elements separated with ;. Now in API version 1 list elements are separated with ,.

For example, in ejabberd 23.10:

$ ejabberdctl get_roster admin localhost
jan@localhost jan   none    subscribe       group1;group2
tom@localhost tom   none    subscribe       group3

Since this ejabberd release, using API version 1:

$ ejabberdctl get_roster admin localhost
jan@localhost jan   none    subscribe       group1,group2
tom@localhost tom   none    subscribe       group3

it is still possible to get the results in the old syntax, using API version 0:

$ ejabberdctl --version 0 get_roster admin localhost
jan@localhost jan   none    subscribe       group1;group2
tom@localhost tom   none    subscribe       group3

@coveralls
Copy link

coveralls commented Dec 1, 2023

Coverage Status

coverage: 32.586% (-0.02%) from 32.602%
when pulling fc13fdc on badlop:api-version-1
into 9756819 on processone:master.

@Neustradamus
Copy link
Contributor

@badlop: Why not v1 to old and v2 to new?

@badlop
Copy link
Member Author

badlop commented Dec 22, 2023

@badlop: Why not v1 to old and v2 to new?

When commands are initially defined, they don't have any version assigned yet: they are version = 0. This is true for all the existing commands, and for any brand new commands defined in the future: they are new, they are not versioned, and by default the have version = 0.

version = 0 :: integer(),

When a command gets some change that would break its API, then that command should get a new definition. And the version number assigned to that new definition will be = API version included in that ejabberd release.

In this sense, when a new ejabberd release includes breaking changes in the API, it will include an API version with increased number.

@badlop badlop added this to the ejabberd 23.xx milestone Dec 26, 2023
Commands that has some argument change:
- add_rosteritem
- oauth_issue_token
- send_direct_invitation
- srg_create
- subscribe_room
- subscribe_room_many
When configured like:
listen:
  -
    request_handlers:
      /api: mod_http_api
      /apizero/v0: mod_http_api

What API version will be used depending on the URL:
- api/commandname use the latest available version
- api/commandname/v0 use version 0
- apizero/v0/commandname use version 0
- apizero/v0/commandname/v2 use version 2
Tuple elements are separated with :
List elements are separated with ,

For example:
  ejabberdctl add_rosteritem user1 localhost testuser7 localhost NickUser77l gr1,gr2,gr3 both
  ejabberdctl create_room_with_opts room1 conference.localhost localhost public:false,persistent:true
  ejabberdctl subscribe_room_many user1@localhost:User1,admin@localhost:Admin room1@conference.localhost urn:xmpp:mucsub:nodes:messages,urn:xmpp:mucsub:nodes:affiliations

Affected commands:
- add_rosteritem
- create_room_with_opts
- oauth_issue_token
- send_direct_invitation
- set_vcard2_multi
- srg_create
- subscribe_room
- subscribe_room_many
@badlop badlop merged commit e26c547 into processone:master Jan 5, 2024
6 checks passed
@badlop badlop deleted the api-version-1 branch January 5, 2024 12:15
@badlop badlop modified the milestones: ejabberd 24.xx, ejabberd 24.02 Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants