nomad-nmr / nomad-server

Server side code for NOMAD system
https://www.nomad-nmr.uk/
GNU Affero General Public License v3.0
3 stars 2 forks source link

V2 RESTful API #143

Open lukasturcani opened 1 month ago

lukasturcani commented 1 month ago

Figured I'd make a tracking issue here to document the design of the v2 API and get feedback as early as possible.

The goal for the new API to be RESTful, which should result in logic on both the backend and frontend being made simpler. By RESTful I mean that the API will be

  1. Stateless: Each request from a client to a server must contain all the information needed to understand and process the request. The server does not store client context between requests.
  2. Resource-Based: RESTful APIs operate on resources, which are identified by URLs. I will discuss the organization of URLs below
  3. HTTP Method-based: RESTful APIs use standard HTTP methods to perform operations on resources: GET: Retrieve data from the server. POST: Send data to the server to create a new resource. PUT: Update an existing resource on the server. DELETE: Remove a resource from the server.
  4. Uniform: the API will have a consistent and standardized way to interact with resources, making it easier to understand and use.

API Design

Resources will be organized as flat as possible. Each resource has a single type. For example, auto and manual experiments have different fields relevant to each kind of experiement, as a result they correspond to different types and are handled by different resources. Nested path should be reserved for

  1. strong parent child relationships: GET /blog/{blog_id}/comments
  2. Containment or Ownership: GET /authors/{author_id}/books

Suggested routes

Query Parameters

Query parameters should act as simple filters. For example GET /api/v2/auto-experiments?solvent=A,B&user=C,D will return all auto experiments where the sovlent is A or B AND user is C or D. Results are returned unsorted unless a sort (+ an optional order) parameters are supplied for example GET /api/v2/auto-experiments?solvent=A,B&user=C,D&sort=title&order=asc

Pagination is also supported by query parameters GET /api/v2/auto-experiments?offset=10&limit=20

Examples

There is no pressing need for the web frontend to actually move onto the v2 api. However, I've selected two examples from the frontend to show how communication with the backend can be made simpler (hopefully!) under the new API.

Experiment table

If using the new API I expect the frontend could display the table of experiments in the following way

the bruker-dataset endpoint can be handled by the backend by returning all unique values of Experiment.datasetName

it is worth noting that in this example we are adding complexity to the frontend while reducing it for the backend. currrently the backend does the heavy-lifting with regard to joining datasets to experiment and interpreting query parameters. By taking this trade-off we gain re-usability of our backend because the endpoints are less opinionated and do fewer things, and our individual endpoints become cheaper as each call does less (eg. you sort only when asked to)

In addition even though the frontend will need to do more work, the work its doing should be more clear and linear than the code currently in the backend.

Legacy Data

Currently the legacyData query parameter does not act as a simple filter. In the v2 api it would be removed. the frontend instead would send different queries depending on if the legacyData switch is toggled.

tomlebl commented 4 weeks ago

@lukasturcani It sounds like a good plan. I have have just couple of comments.

Legacy data switch was added later and current solution is a bit slap&dash. I think what you propose could work. We could laso create a separate endpoint but that could involve quite a bit of code duplication. So, your plan is probably better.

Happy to discuss further if necessary.

lukasturcani commented 2 weeks ago