Using Swagger definition to generate REST client for Jama

Dear Community,

Looking at what Swagger is, it turned out that it is not only a standard way to describe REST APIs, but it has also powerful tools to automatically generate handy client libraries for many different languages (Swagger Codegen).

It turns out that you can download the definition of the interface directly from the JAMA server, run Swagger codegen and start using your nicely (python in my case) REST client.

Well... mostly.

I found two issues:
======================
(1) The security definitions are missing, therefore the basic auth step is missing:
Please add:
    "securityDefinitions": {
        "basicAuth": {
            "type": "basic",
            "description": "HTTP Basic Authentication."
        }
    },
at the top of the defnition (maybe prior to the "definitions" tag) and
also list the security at every endpoint like in:
   "paths" : {
      "/items/{id}/lock" : {
          "get" : {
      "security": [
                  {
                      "basicAuth": []
                  }
      ],
             "description" : "",
  ....
}
See i.e.:
https://github.com/swagger-api/swagger-editor/issues/556

requests/36280 Jama Security definitions


======================
(2) Another problem is that the swagger description defines i.e.  
List[Project] as the return type of the getProjects service, but the
jama server returns the actual List[Project] in the "data" sub-element
of the response. So the deserialisation does not work with any swagger-
codegen generated client.

So the response object definition must consider this for all endpoint
definitions.
======================

I managed to change the downloaded JSON file to fix issue (1) locally and had a workaround for (2) so i have a working client library now, but it would be helpful if the out-of-the-box swagger definition is fixed so other user can generate their clients also and benefit from this.


Kind regards

Hauke

Comments

  • The reason one would want to have a REST api client for Jama is that the client code is more clean and handles several aspects automatically.

    Here is a python sample to get a list of all projects using the generated client:

    import jama_swagger

    def do_list_projects():
        '''
        The list command retreives a list of projects
        '''
        api = jama_swagger.ProjectsApi()
        projects = api.get_projects(max_results=20, start_at=0
        for project in projects:
            print("ID: %s, Key=%s, Title=%s" %
                  (project.id, project.project_key, project.fields["name"]))

    Compare this with the code you write if you use the REST api by using i.e. the "request" python package...

    Actually this would be the api if Jama description was fixed regarding the result object definition...
  • And here is the setup code i am using to supply username / password:

    import getpass
    ...
            jama_password = getpass.getpass(
                    prompt="Enter %s users password for %s:" % (jama_username, jama_swagger.Configuration().host))

            config = jama_swagger.Configuration()
            config.username = jama_username
            config.password = jama_password
            config.debug = True if DEBUG > 0 else False
  • Joshua Patterson
    edited September 2018
    What was your workaround for item 2, I am working with the same problem, I'm using C# not python, but the workaround looks like a massive search and replace on the generated code which I'm really not happy with.
    This seems like an inexcusable lapse in their output api specification; as is it is just completely wrong.

    Any suggestions on how to best deal with this issue would be appreciated.

    What I am currently doing is right before autogenerated deserialization calls, I am inserting this line:
    responseData_ = Newtonsoft.Json.Linq.JObject.Parse(responseData_).GetValue("data").ToString();
    this is C# using newtonsoft's json library. manipulating code autogenerated by nswag studio.
    Basically it generates a node graph, then gets the element data and exports its value as a string, effectively stripping the meta and link elements, as well as the "data" container node leaving just the data as expected according to the incorrect swagger info.