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

Modern RESTful API #1037

Merged
merged 59 commits into from Mar 19, 2017

Conversation

Projects
None yet
7 participants
@vboctor
Member

vboctor commented Feb 25, 2017

This is a proof of concept for Modern RESTful API. It would be good to get early feedback before going too deep with it.

Some of the design aspects:

  • RESTful API with JSON payloads for requests and responses utilizing Slim Framework.
  • Authentication no support for username and password. API tokens are the authentication mechanism.
  • Enable use of API from web UI As we move more towards javascript calling into backend enable JS to call into REST API via cookie based auth. If cookie authentication is used, it will work even if access to REST API is disabled.
  • Enable plugins to publish their own APIs/routes - It should be easy for plugins to extend the REST API with their specific APIs.
  • Support for Swagger and Swagger UI (see example) - use of swagger provides API meta data, ability to generate client code in all languages, and a web UI to play with the API.
  • Time for Breaking changes - Since this is a new API, we can do breaking changes like removing deprecated functionality, fixing in-consistencies (e.g. sometimes returning a user object and sometimes a user id), dropping username/password support, etc.
  • Re-use of code between SOAP and REST - avoid duplicate logic. Eventually deprecate SOAP.
  • Based on proven framework (Slim Framework) - get a bunch of powerful functionality and a proven framework.
  • Use Composer - It's about time we start transitioning to Composer for new dependencies.
  • Private/Internal API - Created a route group /internal for APIs that are private to the web UI.

The focus of this PR is to agree on the approach and provide some basic methods. It is not a goal to implement every single SOAP API functionality. This can be done over time.

@atrol

This comment has been minimized.

Show comment
Hide comment
@atrol

atrol Feb 25, 2017

Member

No time to have a deeper look at the moment, I just would like to be sure that you are aware of #56

Member

atrol commented Feb 25, 2017

No time to have a deeper look at the moment, I just would like to be sure that you are aware of #56

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Feb 25, 2017

Member

@atrol I looked at #56, thanks for pointing it out. It was also utilizing slim framework, but this PR is more comprehensive in aspects like:

  • Authentication model based on API tokens
  • Support for Swagger and Swagger UI
  • RESTful format for the API
  • Re-use of code between SOAP and REST.
  • Using Slim Framework via Composer.
  • Using middleware for features like Auth and Version.

As of now, the PR has a good sample of how the API will look like.

Member

vboctor commented Feb 25, 2017

@atrol I looked at #56, thanks for pointing it out. It was also utilizing slim framework, but this PR is more comprehensive in aspects like:

  • Authentication model based on API tokens
  • Support for Swagger and Swagger UI
  • RESTful format for the API
  • Re-use of code between SOAP and REST.
  • Using Slim Framework via Composer.
  • Using middleware for features like Auth and Version.

As of now, the PR has a good sample of how the API will look like.

Show outdated Hide outdated api/rest/restcore/AuthMiddleware.php
Show outdated Hide outdated api/soap/mc_api.php
@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 1, 2017

Member

I've addressed comments from @rombert + some more improvements

  • REST API is an experimental feature that is disabled by default.
  • Support anonymous access.
  • Some cleanup to SoapObjectFactory and renames to not make it SOAP specific.
  • Added headers + php docs
Member

vboctor commented Mar 1, 2017

I've addressed comments from @rombert + some more improvements

  • REST API is an experimental feature that is disabled by default.
  • Support anonymous access.
  • Some cleanup to SoapObjectFactory and renames to not make it SOAP specific.
  • Added headers + php docs
@syncguru

This comment has been minimized.

Show comment
Hide comment
@syncguru

syncguru Mar 2, 2017

Contributor

Not sure if you've seen this: https://github.com/zircote/swagger-php

Contributor

syncguru commented Mar 2, 2017

Not sure if you've seen this: https://github.com/zircote/swagger-php

@syncguru

Looks good - did not test though.

Show outdated Hide outdated api/soap/mc_api.php
@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 3, 2017

Member

@syncguru I would rather use standard swagger format and leverage tooling (e.g. editor.swagger.io) and documentation for such format, rather than use some other language in php comments that gets translated to swagger and require some build step.

Member

vboctor commented Mar 3, 2017

@syncguru I would rather use standard swagger format and leverage tooling (e.g. editor.swagger.io) and documentation for such format, rather than use some other language in php comments that gets translated to swagger and require some build step.

@rombert

rombert approved these changes Mar 3, 2017

Have not tested, but overall looks good to me.

@rombert

This comment has been minimized.

Show comment
Hide comment
@rombert

rombert Mar 3, 2017

Member

@vboctor - have you given testing any thought? I am not sure whether we can reuse the SOAP tests in the same way we reuse the implementation, but having solid testing on the REST API would be very good IMO.

Member

rombert commented Mar 3, 2017

@vboctor - have you given testing any thought? I am not sure whether we can reuse the SOAP tests in the same way we reuse the implementation, but having solid testing on the REST API would be very good IMO.

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 4, 2017

Member

I've added support for plugins to register their own REST routes / APIs. Also added a sample API with MantisGraph plugin.

Member

vboctor commented Mar 4, 2017

I've added support for plugins to register their own REST routes / APIs. Also added a sample API with MantisGraph plugin.

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 4, 2017

Member

Added support for cookie based auth. This enables javascript code on the web UI to call into the REST API.

Member

vboctor commented Mar 4, 2017

Added support for cookie based auth. This enables javascript code on the web UI to call into the REST API.

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 9, 2017

Member

Added the following functionality:

  • /users/me to get information about the user and accessible projects. More information can be added here as necessary. The goal is to provide info that would be typically needed by a client for the logged in user.
  • /config to get information about a set of provided config options within a user id and project id scope. This supports getting a batch and configs of type arrays, both are not supported by SOAP API. It also provides special handling for enum config options.
  • /lang to get information about a set of strings within the scope of a user id.

TODO: update swagger definition.

Member

vboctor commented Mar 9, 2017

Added the following functionality:

  • /users/me to get information about the user and accessible projects. More information can be added here as necessary. The goal is to provide info that would be typically needed by a client for the logged in user.
  • /config to get information about a set of provided config options within a user id and project id scope. This supports getting a batch and configs of type arrays, both are not supported by SOAP API. It also provides special handling for enum config options.
  • /lang to get information about a set of strings within the scope of a user id.

TODO: update swagger definition.

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 10, 2017

Member

Few more updates

  • Disabling cache via CacheMiddleware
  • Updated swagger.json
  • Updated copyright header
Member

vboctor commented Mar 10, 2017

Few more updates

  • Disabling cache via CacheMiddleware
  • Updated swagger.json
  • Updated copyright header
@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 10, 2017

Member

I've noticed that all configuration options of type array are marked as non-public. This is likely because SOAP API didn't support getting configs of type arrays. I suggest marking them as public as appropriate. That will result in an error if a client attempts to retrieve such configs via SOAP API, but will work fine when retrieving them via the new REST API. The REST APIs also offers getting configs in batch and in context of a user and a project.

The SOAP API is broken anyways in such cases since some configs that are public (e.g. threshold) can be an integer (common case) or an array (e.g. when set via web UI).

Member

vboctor commented Mar 10, 2017

I've noticed that all configuration options of type array are marked as non-public. This is likely because SOAP API didn't support getting configs of type arrays. I suggest marking them as public as appropriate. That will result in an error if a client attempts to retrieve such configs via SOAP API, but will work fine when retrieving them via the new REST API. The REST APIs also offers getting configs in batch and in context of a user and a project.

The SOAP API is broken anyways in such cases since some configs that are public (e.g. threshold) can be an integer (common case) or an array (e.g. when set via web UI).

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 12, 2017

Member

The following improvements were added:

  • Use RestFault instead of SoapFault for REST API
  • Depending on the error, use the appropriate http status code.
  • Added ability to delete issues.
  • Improve json info returned for related issues.
  • Added configs of type arrays that were missing from public configs list.
Member

vboctor commented Mar 12, 2017

The following improvements were added:

  • Use RestFault instead of SoapFault for REST API
  • Depending on the error, use the appropriate http status code.
  • Added ability to delete issues.
  • Improve json info returned for related issues.
  • Added configs of type arrays that were missing from public configs list.
@dregad

This comment has been minimized.

Show comment
Hide comment
@dregad

dregad Mar 14, 2017

Member

@vboctor I think it's truly great that Mantis will offer REST API, and I strongly support the idea.

That said, I regretfully do not have enough free time for a proper, in-depth review, actually test the API or to effectively contribute to the effort, there is just too much on my plate these days. Being aware of the benefits a modern webservice interface, and the fact that it's an often requested feature, I would not want to delay its implementation without good reason.

As an overall comment, I trust you have fully and globally analyzed the interface endpoints, as this is a promise to the webservice's consumers that can't easily (shouldn't) be changed down the line. I think it's very important that we have an overall consistency in the API, so we it would be useful to have a vision/roadmap to avoid adding mismatched bits and pieces as we go along. This should be documented somewhere (wiki ?)

More detailed review follows.

Member

dregad commented Mar 14, 2017

@vboctor I think it's truly great that Mantis will offer REST API, and I strongly support the idea.

That said, I regretfully do not have enough free time for a proper, in-depth review, actually test the API or to effectively contribute to the effort, there is just too much on my plate these days. Being aware of the benefits a modern webservice interface, and the fact that it's an often requested feature, I would not want to delay its implementation without good reason.

As an overall comment, I trust you have fully and globally analyzed the interface endpoints, as this is a promise to the webservice's consumers that can't easily (shouldn't) be changed down the line. I think it's very important that we have an overall consistency in the API, so we it would be useful to have a vision/roadmap to avoid adding mismatched bits and pieces as we go along. This should be documented somewhere (wiki ?)

More detailed review follows.

@dregad

Some thoughts about the introduction of Composer, and its implications.

  • Are you planning to publish MantisBT on packagist.org ?
  • Replacing submodules by composer dependencies ?
  • Documenting (dev guide) the need to run composer install,
  • The release process in the wiki needs an update as well
@@ -18,3 +18,6 @@
path = library/parsedown
url = https://github.com/mantisbt/parsedown.git
branch = mantisbt
[submodule "api/rest/swagger"]

This comment has been minimized.

@dregad

dregad Mar 14, 2017

Member

I am not familiar with swagger and how it works, does it have to be physically under the api/rest directory for it to work ? If not, I would suggest to move the submodule to /library, with the other external libs.

In any case, the submodule should be documented (in library/README.md, or elsewhere)

@dregad

dregad Mar 14, 2017

Member

I am not familiar with swagger and how it works, does it have to be physically under the api/rest directory for it to work ? If not, I would suggest to move the submodule to /library, with the other external libs.

In any case, the submodule should be documented (in library/README.md, or elsewhere)

This comment has been minimized.

@vboctor

vboctor Mar 15, 2017

Member

There is two components to swagger:

  • Swagger.json - It is the meta-data describing the APIs exposed by the RESTful service (equivalent of WSDL for SOAP). This file is used to power Swagger UI or code generators that generate clients in multiple languages based on Swagger meta-data.
  • Swagger UI - This is a JS web app that reads such swagger.json and provides the page that describes all APIs including documentation, authentication support, etc. API consumers can use this UI to understand the API as well as try it out. Think of it like a SoapUI or one of these tools. Bundling this enables that for any MantisBT instance.
@vboctor

vboctor Mar 15, 2017

Member

There is two components to swagger:

  • Swagger.json - It is the meta-data describing the APIs exposed by the RESTful service (equivalent of WSDL for SOAP). This file is used to power Swagger UI or code generators that generate clients in multiple languages based on Swagger meta-data.
  • Swagger UI - This is a JS web app that reads such swagger.json and provides the page that describes all APIs including documentation, authentication support, etc. API consumers can use this UI to understand the API as well as try it out. Think of it like a SoapUI or one of these tools. Bundling this enables that for any MantisBT instance.
@@ -0,0 +1,4 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

This comment has been minimized.

@dregad

dregad Mar 14, 2017

Member

Some comments documenting what the rewrite rule is doing and for what purpose would be useful.

@dregad

dregad Mar 14, 2017

Member

Some comments documenting what the rewrite rule is doing and for what purpose would be useful.

This comment has been minimized.

@vboctor

vboctor Mar 15, 2017

Member

Done. Added a comment that references http://docs.slimframework.com/routing/rewrite/

@vboctor

vboctor Mar 15, 2017

Member

Done. Added a comment that references http://docs.slimframework.com/routing/rewrite/

/**
* A webservice interface to Mantis Bug Tracker
*
* @package MantisBT

This comment has been minimized.

@dregad

dregad Mar 14, 2017

Member

Add @subpackage REST_API ? (this comment is valid for all of the new files/classes)

@dregad

dregad Mar 14, 2017

Member

Add @subpackage REST_API ? (this comment is valid for all of the new files/classes)

This comment has been minimized.

@vboctor

vboctor Mar 15, 2017

Member

Existing SOAP files don't have a sub-package defined. I don't think it is a big deal, but if we add it we should probably use webservice or webapi since there is a lot of shared code between SOAP and REST.

@vboctor

vboctor Mar 15, 2017

Member

Existing SOAP files don't have a sub-package defined. I don't think it is a big deal, but if we add it we should probably use webservice or webapi since there is a lot of shared code between SOAP and REST.

}
}
/**

This comment has been minimized.

@dregad

dregad Mar 14, 2017

Member

Move class to dedicated file, include via autoloader (or manual include if needed).

Maybe a good idea to do the same for ApiObjectsFactory as well.

@dregad

dregad Mar 14, 2017

Member

Move class to dedicated file, include via autoloader (or manual include if needed).

Maybe a good idea to do the same for ApiObjectsFactory as well.

This comment has been minimized.

@vboctor

vboctor Mar 15, 2017

Member

Will defer auto-loader work out this of review. I would like to think it through along with wider composer usage.

@vboctor

vboctor Mar 15, 2017

Member

Will defer auto-loader work out this of review. I would like to think it through along with wider composer usage.

Show outdated Hide outdated api/soap/mc_config_api.php
Show outdated Hide outdated api/rest/index.php
Show outdated Hide outdated api/rest/index.php
Show outdated Hide outdated api/rest/index.php
Show outdated Hide outdated composer.json
Show outdated Hide outdated composer.json
@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 15, 2017

Member

Answering @dregad 's questions about composer:

Are you planning to publish MantisBT on packagist.org ?

No. I think of it more like an app than a package that others would want to re-use via composer.

Replacing submodules by composer dependencies ?

Probably, specially for components that are published as composer packages.

Documenting (dev guide) the need to run composer install,

Will do.

The release process in the wiki needs an update as well

I'm planning to do something there, but I'm hoping I would update the packaging script rather than adding an extra step. Basically something along the lines of if you find composer.json then run composer install. This way the packaging works with both old and new releases.

I would also like over time to have the packaging script handle high level steps, and rely on a scripts in the source tree for MantisBT to do some of the micro steps. That has two benefits: 1. such steps are likely to overlap with MantisBT build, 2. the micro-steps can be different per branch, but the package process will still work.

Member

vboctor commented Mar 15, 2017

Answering @dregad 's questions about composer:

Are you planning to publish MantisBT on packagist.org ?

No. I think of it more like an app than a package that others would want to re-use via composer.

Replacing submodules by composer dependencies ?

Probably, specially for components that are published as composer packages.

Documenting (dev guide) the need to run composer install,

Will do.

The release process in the wiki needs an update as well

I'm planning to do something there, but I'm hoping I would update the packaging script rather than adding an extra step. Basically something along the lines of if you find composer.json then run composer install. This way the packaging works with both old and new releases.

I would also like over time to have the packaging script handle high level steps, and rely on a scripts in the source tree for MantisBT to do some of the micro steps. That has two benefits: 1. such steps are likely to overlap with MantisBT build, 2. the micro-steps can be different per branch, but the package process will still work.

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 15, 2017

Member

@dregad I think I addressed all your feedback.

@vboctor I think it's truly great that Mantis will offer REST API, and I strongly support the idea.

Great. I'm very excited as well. I think it will make a big difference and it is definitely one of the main aspects of MantisBT that needed fresh paint 👍

That said, I regretfully do not have enough free time for a proper, in-depth review, actually test the API or to effectively contribute to the effort, there is just too much on my plate these days. Being aware of the benefits a modern webservice interface, and the fact that it's an often requested feature, I would not want to delay its implementation without good reason.

No worries, I will drive this.

As an overall comment, I trust you have fully and globally analyzed the interface endpoints, as this is a promise to the webservice's consumers that can't easily (shouldn't) be changed down the line. I think it's very important that we have an overall consistency in the API, so we it would be useful to have a vision/roadmap to avoid adding mismatched bits and pieces as we go along. This should be documented somewhere (wiki ?)

I'm starting the API disabled by default and we will advertise it as preview/beta/experimental with potential breaking changes. I will review and test, but I think we will benefit from having more people play with it and provide feedback. Also open it up for plugins to start building their APIs.

As for the guidelines, I started a gist with the guidelines. We can move it to the wiki once it is stable.

Member

vboctor commented Mar 15, 2017

@dregad I think I addressed all your feedback.

@vboctor I think it's truly great that Mantis will offer REST API, and I strongly support the idea.

Great. I'm very excited as well. I think it will make a big difference and it is definitely one of the main aspects of MantisBT that needed fresh paint 👍

That said, I regretfully do not have enough free time for a proper, in-depth review, actually test the API or to effectively contribute to the effort, there is just too much on my plate these days. Being aware of the benefits a modern webservice interface, and the fact that it's an often requested feature, I would not want to delay its implementation without good reason.

No worries, I will drive this.

As an overall comment, I trust you have fully and globally analyzed the interface endpoints, as this is a promise to the webservice's consumers that can't easily (shouldn't) be changed down the line. I think it's very important that we have an overall consistency in the API, so we it would be useful to have a vision/roadmap to avoid adding mismatched bits and pieces as we go along. This should be documented somewhere (wiki ?)

I'm starting the API disabled by default and we will advertise it as preview/beta/experimental with potential breaking changes. I will review and test, but I think we will benefit from having more people play with it and provide feedback. Also open it up for plugins to start building their APIs.

As for the guidelines, I started a gist with the guidelines. We can move it to the wiki once it is stable.

vboctor added some commits Feb 25, 2017

Add Composer
- Added composer.json
- Update .gitignore
Add version middleware
Stamp MantisBT version as X-Mantis-Version response header.
Added Swagger meta data and UI
The swagger will enable tools to generate client libraries for MantisBT.
It also provides a nice sandbox to test the API from the browser, see
http://petstore.swagger.io for an example.
Make serialization code REST friendly
This removes SOAP specific serialization logic in case of REST.
Add ‘Authorize’ support to Swagger
Now the swagger definition declares the authentication mechanism and enables in Swagger UI.

vboctor added some commits Mar 10, 2017

Support creating issues via REST API
- Support creating issues by posting to issues API url.
- Some improvements for get issue.
Refactoring error handling for REST API
Use RestFault instead of SoapFault in case of REST API and
make sure the proper http status code is surfaced based on error.
Improve http status code handling
- Add constants to constant_inc.php
- Create a fault method per error status code.
Plugin routes under /api/rest/plugins/Example
- Add an API to provide the name for the route group.
- Update MantisGraph to use the new API.
- Update documentation to be reference new API, new pattern, and reference
Slim Framework Router documentation.
Update ApiEnabled/Auth middleware
- Move MantisOffline check for API enabled rather than Auth middleware.
- Auth middleware checks that read-only threshold is matched after authentication.
- Use http status code constants
Move plugin routes after core routes
Slim Framework will reject conflicting route anyways, but didn’t
to make it clear that core runs first, then plugins. Also if someone
debugs the code, it is clear that the error is in the plugins rather than
core.
Support for API calls from the Web UI
1. Remove support for cookie auth on authorization header and just use cookies.
2. Even if the API is disabled, it should still work for calls via cookie auth to serve the UI.
3. Add internal route for private APIs and use it for autocomplete functionality.
4. Remove xmlhttprequest.php / xmlhttprequest_api.php.
5. Add constants for headers, login methods and middleware attributes.
Change langGet and configGet to return normal arrays
Return regular arrays rather than associative arrays.
Note that configGet may return an associative array
as the value of a configuration option.

@vboctor vboctor merged commit 252ae00 into mantisbt:master Mar 19, 2017

1 check was pending

continuous-integration/travis-ci/pr The Travis CI build is in progress
Details
@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 19, 2017

Member

Few extra changes:

  • Support cookie based auth using cookies rather than cookie value in authorization header.
  • Created a route group /internal for APIs that are private to the web UI.
  • Added API for auto-complete for platform, OS and OS build. Use REST API to power auto-complete instead of xmlhttprequest_api.php and xmlhttprequest.php.
  • Disabling REST API only impacts api-token auth and not cookie auth, to keep the UI working.
  • Use regular arrays rather than associating arrays for cases where we are not returning objects with pre-defined keys
  • Updated swagger.json to add new APIs, schemas for POST and response data objects, and fix some schema errors.
Member

vboctor commented Mar 19, 2017

Few extra changes:

  • Support cookie based auth using cookies rather than cookie value in authorization header.
  • Created a route group /internal for APIs that are private to the web UI.
  • Added API for auto-complete for platform, OS and OS build. Use REST API to power auto-complete instead of xmlhttprequest_api.php and xmlhttprequest.php.
  • Disabling REST API only impacts api-token auth and not cookie auth, to keep the UI working.
  • Use regular arrays rather than associating arrays for cases where we are not returning objects with pre-defined keys
  • Updated swagger.json to add new APIs, schemas for POST and response data objects, and fix some schema errors.
@rombert

This comment has been minimized.

Show comment
Hide comment
@rombert

rombert Mar 20, 2017

Member

@vboctor - I'm still curious to see how you plan to approach testing.

Member

rombert commented Mar 20, 2017

@vboctor - I'm still curious to see how you plan to approach testing.

@vboctor

This comment has been minimized.

Show comment
Hide comment
@vboctor

vboctor Mar 23, 2017

Member

@rombert I started working on this, then figured out that it is hard to test without having more operations available via the REST API to enable full test cycles. So will revisit later. It shouldn't be hard to test a REST API.

Member

vboctor commented Mar 23, 2017

@rombert I started working on this, then figured out that it is hard to test without having more operations available via the REST API to enable full test cycles. So will revisit later. It shouldn't be hard to test a REST API.

@vboctor vboctor self-assigned this Mar 26, 2017

@vboctor vboctor referenced this pull request Mar 26, 2017

Closed

Json api #6

@vboctor vboctor deleted the vboctor:rest-api branch Mar 29, 2017

@imbabaer

This comment has been minimized.

Show comment
Hide comment
@imbabaer

imbabaer Dec 6, 2017

Docu for creating issues with POST request:
POST-Datastructure:
"{"project": {"name":"proj-name", "id":1232}, "summary":"text", "description":"text", "category":"category-name"}"

imbabaer commented Dec 6, 2017

Docu for creating issues with POST request:
POST-Datastructure:
"{"project": {"name":"proj-name", "id":1232}, "summary":"text", "description":"text", "category":"category-name"}"

* @return \Slim\Http\Response The augmented response.
*/
function rest_issue_add( \Slim\Http\Request $p_request, \Slim\Http\Response $p_response, array $p_args ) {
$t_issue = $p_request->getParsedBody();

This comment has been minimized.

@Ashwin-Kapes

Ashwin-Kapes Dec 29, 2017

What's the format for JSON body to post an Issue?

@Ashwin-Kapes

Ashwin-Kapes Dec 29, 2017

What's the format for JSON body to post an Issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment