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

Update the schema for the REST API specification #42346

Merged
merged 2 commits into from
Aug 15, 2019
Merged

Conversation

karmi
Copy link
Contributor

@karmi karmi commented May 22, 2019

The purpose of this patch is to improve the schema of the Elasticsearch REST API specification.

It tries to solve a number of outstanding issues with the current specification, and to make the schema more open for future extension. It requires the consumers — eg. the client code generators — to update their code, but the long-term benefits should be worth it.

A brief overview of the changes:

  • It enhances the support for deprecated paths, introduced in fix #35262 define deprecations of API's as a whole and urls #39063
  • It changes the specification of URL paths: instead of a list of strings, it uses a list of objects, to encode eg. the method and path combination.
  • It adds a sharp and concise description to each API endpoint, to be used eg. in generated code annotations.

A snippet of the new schema, copied from the "Create" API, looks like this:

{
"url":{
  "paths":[
    {
      "path":"/{index}/_create/{id}",
      "method":"PUT",
      "parts":{
        "id":{
          "type":"string",
          "required":true,
          "description":"Document ID"
        },
        "index":{
          "type":"string",
          "required":true,
          "description":"The name of the index"
        }
      }
    },
    {
      "path":"/{index}/{type}/{id}/_create",
      "method":"PUT",
      "parts":{
        "id":{
          "type":"string",
          "required":true,
          "description":"Document ID"
        },
        "index":{
          "type":"string",
          "required":true,
          "description":"The name of the index"
        },
        "type":{
          "type":"string",
          "description":"The type of the document",
          "deprecated":true
        }
      },
      "deprecated":{
        "version":"7.0.0",
        "description":"Specifying types in urls has been deprecated"
      }
    }
  ]
}}

The URL paths are no longer defined as a list of strings, with disconnected parts and method elements outside the definition. Instead, every path now lists the HTTP method to use, and the dynamic parts it contains. It also defines whether this path has been deprecated, instead of using an extra key, deprecated_paths, as before. For the cost of a little duplication, each dynamic part can now be marked as deprecated, directly in the path definition.

The dubious top-level path element has been removed: the original idea was to consider it as the "canonical" path, but in practice, the specification consumers never had a good use for it, and the ambiguity between path and paths created a lot of confusion.

The params and body elements have been left intact, as well as the recently introduced deprecated element.

Another breaking change is that the documentation element has been transformed to an object. Apart from the existing url key, it adds a description key, which contains a concise description of the API endpoint. These descriptions are used in the client code generators, and they have to be written carefully — they are displayed prominently on the documentation websites for various languages, for example on godoc.org:

api-description-godoc

To allow the code generators work with a freeform text like this, the description has to be a full sentence, and has to start with a verb. Multiple lines are allowed.

One outstanding question is whether we should drop support for multiple HTTP methods in the endpoint definition, as this patch does. After some thinking and conversations, I think it's the right thing to do: a mere list of methods doesn't contain any information if there's any difference (for example in case of the "Create" API), and in some cases (the "Search" API), the listed methods are included as "optional", trying to encode certain leniency in the Elasticsearch API. This is probably confusing to specification readers, and doesn't have much value in the end.

To make the updates, I've created a Ruby script to load the old JSON files (json_spec_update.rb.txt), and generate the files with a new schema. I'm using another Ruby script (json_spec_retouch.rb.txt) to "retouch" the new files, when needed.

Related:

/cc @elastic/es-clients

@karmi karmi self-assigned this May 22, 2019
@javanna
Copy link
Member

javanna commented May 22, 2019

I had a look and I think the changes are a good improvement of our spec. For instance, for years it was hard to associate paths with their corresponding parts. I think though that we should keep, at least for now, multiple methods. Take bulk for instance (but this applies to many API), it supports POST and PUT for all of its paths. I would not want to see only POST in the spec unless the corresponding code supports only POST. Or rather, if we do want to make such change, I would like to make it separately from this refactoring and give it more visibility, have a separate discussions about it and so on.

If you adapt that I can take a stab at updating the java code in the yaml test runner so we get a green build and we can move this forward.

@karmi
Copy link
Contributor Author

karmi commented May 22, 2019

I've re-introduced the multiple methods for endpoint in c6193e1.

@cbuescher cbuescher added :Core/Infra/REST API REST infrastructure and utilities >enhancement labels May 27, 2019
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@codebrain
Copy link
Contributor

This is a move in a good direction for the clients team.
❤️

"parts":{
"id":{
"type":"string",
"required":true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can get rid of the required flag here, now that parts are listed under their own path. All parts are then required in the path that they are part of.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good good catch! The required property is indeed redunant in the new format, since effectively all the dynamic parts in a specific path are required.

@javanna
Copy link
Member

javanna commented Jun 6, 2019

heya I have adapted the yaml test runner and merged master in. Also left a comment on removing the required flag from path parts. The path resolution logic is much more straight-forward now, which demonstrates that this is a good change. Let's see if tests are green.

@javanna
Copy link
Member

javanna commented Jun 6, 2019

Tests seem to be red because there are more spec files that need to be converted to the new format. I think that besides ./rest-api-spec/src/main/resources/rest-api-spec/api/, spec are at least also under ./x-pack/plugin/src/test/resources/rest-api-spec/api/, and there's one here too: ./plugins/examples/rest-handler/src/test/resources/rest-api-spec/api/cat.example.json

@karmi
Copy link
Contributor Author

karmi commented Jul 22, 2019

I've re-generated the JSON files for Core APIs from current master (picking up the new stability field), generated the JSON files for X-Pack APIs, and cherry-picked the changes to the Java test runner.

@karmi
Copy link
Contributor Author

karmi commented Jul 22, 2019

Jenkins, retest this please.

@javanna
Copy link
Member

javanna commented Aug 13, 2019

I fixed a couple of test issues I found:

  • the index API needed to be adapted as endpoints without it don't support PUT
  • the indices.close new API needed to be converted
  • one failing unit test due to the addition of the "stability" field in the spec

and rebased the branch on current master, which had a lot of conflicts due to #44487 .

@javanna
Copy link
Member

javanna commented Aug 13, 2019

retest this please

@elasticcla
Copy link

Hi @karmi, we have found your signature in our records, but it seems like you have signed with a different e-mail than the one used in your Git commit. Can you please add both of these e-mails into your Github profile (they can be hidden), so we can match your e-mails to your Github profile?

@javanna javanna marked this pull request as ready for review August 13, 2019 22:43
@javanna
Copy link
Member

javanna commented Aug 15, 2019

run elasticsearch-ci/bwc

@javanna javanna force-pushed the rest_spec_update branch 2 times, most recently from 619df14 to c282def Compare August 15, 2019 12:47
This patch updates the REST API spefication in JSON files to better encode deprecated entities,
to improve specification of URL paths, and to open up the schema for future extensions.

Notably, it changes the `paths` from a list of strings to a list of objects, where each
particular object encodes all the information for this particular path: the `parts` and the `methods`.

Among the benefits of this approach is eg. encoding the difference between using the `PUT` and `POST`
methods in the Index API, to either use a specific document ID, or let Elasticsearch generate one.

Also `documentation` becomes an object that supports an `url` and also a `description` which is a
new field.
@javanna javanna changed the title [WIP] Change the schema for the REST API specification Update the schema for the REST API specification Aug 15, 2019
The logic for choosing the path to use when running tests has been
simplified, as a consequence of the path parts being listed under each
path in the spec. The special case for create and index has been removed.

Also the parsing code has been hardened so that errors are thrown earlier
when the structure of the spec differs from what expected, and their
error messages should be more helpful.
javanna pushed a commit to javanna/elasticsearch that referenced this pull request Aug 16, 2019
* Update the REST API specification

This patch updates the REST API spefication in JSON files to better encode deprecated entities,
to improve specification of URL paths, and to open up the schema for future extensions.

Notably, it changes the `paths` from a list of strings to a list of objects, where each
particular object encodes all the information for this particular path: the `parts` and the `methods`.

Among the benefits of this approach is eg. encoding the difference between using the `PUT` and `POST`
methods in the Index API, to either use a specific document ID, or let Elasticsearch generate one.

Also `documentation` becomes an object that supports an `url` and also a `description` which is a
new field.

* Adapt YAML runner to new REST API specification format

The logic for choosing the path to use when running tests has been
simplified, as a consequence of the path parts being listed under each
path in the spec. The special case for create and index has been removed.

Also the parsing code has been hardened so that errors are thrown earlier
when the structure of the spec differs from what expected, and their
error messages should be more helpful.
javanna added a commit that referenced this pull request Aug 16, 2019
* Update the REST API specification

This patch updates the REST API spefication in JSON files to better encode deprecated entities,
to improve specification of URL paths, and to open up the schema for future extensions.

Notably, it changes the `paths` from a list of strings to a list of objects, where each
particular object encodes all the information for this particular path: the `parts` and the `methods`.

Among the benefits of this approach is eg. encoding the difference between using the `PUT` and `POST`
methods in the Index API, to either use a specific document ID, or let Elasticsearch generate one.

Also `documentation` becomes an object that supports an `url` and also a `description` which is a
new field.

* Adapt YAML runner to new REST API specification format

The logic for choosing the path to use when running tests has been
simplified, as a consequence of the path parts being listed under each
path in the spec. The special case for create and index has been removed.

Also the parsing code has been hardened so that errors are thrown earlier
when the structure of the spec differs from what expected, and their
error messages should be more helpful.
@cjcenizal
Copy link
Contributor

Thank you for the clear PR description @karmi and for the broadcast email @Mpdreamz! They were both immensely helpful for the ES UI team.

I see a number of breaking changes here which impact the ES UI team's maintenance workflow for Kibana Console (addressed by elastic/kibana#43427). This isn't terribly disruptive for us, but could we please add the >breaking label to this PR? And in the future would it be possible to add the >breaking label to any PRs that change an interface published by this repo, including the REST API spec? Thanks!

delvedor added a commit that referenced this pull request Sep 16, 2019
delvedor added a commit to delvedor/elasticsearch that referenced this pull request Sep 16, 2019
delvedor added a commit to delvedor/elasticsearch that referenced this pull request Sep 16, 2019
delvedor added a commit that referenced this pull request Sep 17, 2019
spalger pushed a commit to elastic/elasticsearch-js-legacy that referenced this pull request Sep 19, 2019
javanna pushed a commit that referenced this pull request Sep 19, 2019
Follow up from #42346. Since the `methods` array is in order of
preference when calling the index API with an `{id}` we prefer to use
the `PUT` http method.
javanna pushed a commit that referenced this pull request Sep 19, 2019
Follow up from #42346. Since the `methods` array is in order of
preference when calling the index API with an `{id}` we prefer to use
the `PUT` http method.
javanna pushed a commit that referenced this pull request Sep 23, 2019
karmi added a commit to elastic/go-elasticsearch that referenced this pull request Oct 1, 2019
karmi added a commit to elastic/go-elasticsearch that referenced this pull request Oct 2, 2019
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.

None yet

9 participants