mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
173 lines
7.8 KiB
ReStructuredText
173 lines
7.8 KiB
ReStructuredText
API Design Guidelines
|
|
=====================
|
|
|
|
The following section outlines guidelines related to extending and/or modifying
|
|
the Galaxy API. The Galaxy API has been developed over time in an ad-hoc fashion and by
|
|
many contributors, so clients SHOULD NOT expect the API will conform to
|
|
these guidelines - but developers contributing to the Galaxy API SHOULD follow
|
|
these guidelines.
|
|
|
|
Before Getting Started
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Developers should familiarize themselves with `HTTP method definitions
|
|
<https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9>`__. While Galaxy
|
|
follows these imperfectly - a serious effort should be made to use HTTP
|
|
methods (GET, POST, PUT, DELETE, etc.) correctly and consistently. More
|
|
information about these methods with a focus on RESTful APIs can be found
|
|
at https://restfulapi.net/http-methods/.
|
|
|
|
Developers should also familiarize themselves with the `HTTP status code definitions
|
|
<http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>`__. The API responses
|
|
should properly set the status code according to the result - in particular
|
|
2XX responses should be used for successful requests, 4XX for various
|
|
kinds of client errors, and 5XX for the errors on the server side.
|
|
|
|
Finally, developers should familiarize themselves with `RESTful API design
|
|
<https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design>`__.
|
|
Again, Galaxy follows generic RESTful guidelines imperfectly, but a serious
|
|
effort should be made to design the API as RESTfully and consistently as possible.
|
|
|
|
Documenting the API
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
An API endpoint implementation method should include high-level docstring documentation
|
|
for consumption at docs.galaxyproject.org.
|
|
|
|
API functionality should consume and produce Pydantic_ `models
|
|
<https://pydantic-docs.helpmanual.io/usage/models/>`__ with typed and annotated
|
|
`fields <https://pydantic-docs.helpmanual.io/usage/types/>`__. This information
|
|
will be used to generate detailed OpenAPI_ documentation for APIs in
|
|
the near future. Typed models also improve the quality and thoroughness
|
|
of the static checking that can be done for the Galaxy backend.
|
|
|
|
To further document your API and allow other developers to see how it functions,
|
|
new API functionality should include functional tests. These functional
|
|
tests should be implemented in Python and added to either the API test suite
|
|
or the integration test suite. Checkout the :doc:`Writing Tests for Galaxy <writing_tests>`
|
|
documentation for more information on developing tests for Galaxy.
|
|
|
|
.. note::
|
|
|
|
The Galaxy documentation can be generated by running ``make docs-develop``
|
|
from the Galaxy root. Galaxy can be type checked by running ``tox -e mypy``
|
|
from the root of Galaxy after tox_ has been configured.
|
|
|
|
Error Handling
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
API methods should throw a finite number of exceptions
|
|
(defined in :mod:`galaxy.exceptions`) and these should subclass
|
|
:class:`galaxy.exceptions.MessageException` and not paste/WSGI/FastAPI HTTP exceptions.
|
|
When possible, the framework itself should be responsible for catching these exceptions,
|
|
setting the status code, and building an error response. Throwing these exceptions
|
|
will ensure the API responses are consistent across frameworks and across the API.
|
|
These exceptions allow throwers to attach arbitrary extra information.
|
|
|
|
Error responses should not consist of plain text strings - they should be
|
|
dictionaries describing the error and containing the following:
|
|
|
|
.. code-block: json
|
|
|
|
{
|
|
"status_code": 400,
|
|
"err_code": 400007,
|
|
"err_msg": "Request contained invalid parameter, action could not be completed.",
|
|
"type": "error",
|
|
"extra_error_info": "Extra information."
|
|
}
|
|
|
|
The error code (``err_code``) is defined by the exception class
|
|
and pulled from ``lig/galaxy/exceptions/error_codes.json``. This JSON
|
|
document should be used to add new error conditions or improve
|
|
default error messages.
|
|
|
|
If there is an error processing some part of the request (one item in a list
|
|
for instance), the status code should be set to reflect the error and the
|
|
partial result may or may not be returned depending on the controller -
|
|
this behavior should be documented.
|
|
|
|
Backward Compatibility
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Backward compatibility is important and should be maintained when possible.
|
|
If changing behavior in a non-backward compatible way please ensure one
|
|
of the following holds - there is a strong reason to believe no consumers
|
|
depend on the old behavior, the behavior is effectively broken, or the API
|
|
method being modified has not been part of a tagged dist release. If these
|
|
conditions do not hold, please help the Galaxy release manager ensure
|
|
information about the breaking API is highlighted in the Galaxy release
|
|
notes.
|
|
|
|
Whenever functionality needs to be added, removed, or modified that
|
|
breaks backward compatibility in a significant way to a component used by
|
|
the community - a "dev" variant of the API should be established and
|
|
the community should be alerted and given a time frame for when the old
|
|
behavior will be replaced with the new behavior.
|
|
|
|
Design
|
|
~~~~~~
|
|
|
|
Functionality should not be copied and pasted between controllers -
|
|
consider refactoring functionality into associated classes or short of
|
|
that into mixins_ or into managers (:mod:`galaxy.managers`).
|
|
|
|
To whatever degree is possible, the Galaxy API controller classes
|
|
(found in :mod:`galaxy.webapps.galaxy.api`) should be as lean as
|
|
possible. Most of the logic should be pushed into components that
|
|
are decoupled from the actual web application and the web framework.
|
|
The role of the controller should be simply to adapt the web request
|
|
(tied to the web framework) to simple objects (plain Python objects,
|
|
Pydantic_ models, or SQLAlchemy models), send these objects to a
|
|
Python component lower in the stack, and finally to translate the
|
|
response to a web response. This design will ensure that Galaxy
|
|
application logic is usable in as many contexts as possible and
|
|
decouple the core "business logic" of Galaxy from the web framework
|
|
hosting it.
|
|
|
|
Going forward, we anticipate the most typical way this abstract
|
|
advice translates to concrete code flow is that API controllers
|
|
in :mod:`galaxy.webapps.galaxy.api` receive or produce Pydantic_
|
|
models and pass them to manager components defined in
|
|
:mod:`galaxy.managers`. The manager is then responsible for
|
|
interacting with the whole backend or specific components to
|
|
fullfil the desired request.
|
|
|
|
Galaxy work contexts provide a way for API requests (and other
|
|
components) to describe what they require from the framework
|
|
in terms of the request (examples include the Galaxy app, a user
|
|
to act on behalf of, or a user with a defined "current history").
|
|
These objects describing the web request are passed around rather
|
|
haphazardly as an argument named ``trans``. To design API methods
|
|
to deal with ``trans`` in the most statically checkable and
|
|
rigorous way - please review the docs for :mod:`galaxy.managers.context`.
|
|
|
|
Examples
|
|
~~~~~~~~
|
|
|
|
A very clean, isolated example of a well documented controller
|
|
and well annotated models is the licenses endpoint -
|
|
:mod:`galaxy.webapps.galaxy.api.licenses`. A more complicated
|
|
endpoint that demonstrates working with a manager and the
|
|
Galaxy model backend is the roles endpoint - :mod:`galaxy.webapps.galaxy.api.roles`.
|
|
|
|
BioBlend
|
|
~~~~~~~~
|
|
|
|
Changes to reflect modifications to the API should be pushed upstream to
|
|
the BioBlend_ project if possible.
|
|
|
|
Longer Term Goals
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
- It would be advantageous to have a clearer separation of anonymous and
|
|
admin handling functionality.
|
|
- Consistent standards for range-based requests, batch requests, filtered
|
|
requests, etc... should be established and documented here.
|
|
|
|
.. _Pydantic: https://pydantic-docs.helpmanual.io/
|
|
.. _BioBlend: https://github.com/galaxyproject/bioblend
|
|
.. _mixins: http://en.wikipedia.org/wiki/Composition_over_inheritance
|
|
.. _tox: https://tox.readthedocs.io/en/latest/
|
|
.. _OpenAPI: https://www.openapis.org
|