Skip to content

Commit

Permalink
fifth pass on data requests
Browse files Browse the repository at this point in the history
  • Loading branch information
xnought committed May 2, 2024
1 parent 4f8d2dd commit ec572d2
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,39 @@ def test_overview():

would trigger if a `GET` request to the backend at route `test/overview` was received and would respond with the JSON of `{"helloThere": "world"}`. As you can see `TestOverviewResponse` object is transformed in JSON on the response and the variables are switched from snake_case to camelCase.

Please see examples in the [`backend/src/api/protein.py`](../backend/src/api/protein.py).
Please see examples in the [`backend/src/api/protein.py`](../backend/src/api/protein.py).

## Fifth pass

This entire 5th pass is dedicated to how we request data from the [`backend`](../backend/) from the [`frontend`](../frontend/).

Like I said, we make HTTP requests in the frontend, but you check our entire frontend you won't find a single `fetch()` request.

We use a library called `openapi-typescript-codegen` which reads the Python endpoint definition and generates/compiles each as a frontend function we can simply import.

For example, take the `POST` endpoint for how we search for proteins in [`search.py`](../backend/src/api/search.py) at `/search/proteins` which is defined like

```python
@router.post("/search/proteins", response_model=SearchProteinsResults)
def search_proteins(body: SearchProteinsBody):
# code not shown...
```

when I run `./run.sh gen_api`, I use `openapi-typescript-codegen` which reads the python function name, the endpoint, the return type, and the input type and transpiles it into a custom `fetch()` call to the backend that our frontend can super easily use (with type info!).

Then, all I have to do is import the `Backend` object in the frontend and use the function with the same name I defined in python (but with camelCase):

```ts
import { Backend } from "../lib/backend";

const { proteinEntries, totalFound } = await Backend.searchProteins({
query: "kinase",
});
```

which under the hood make a HTTP `POST` request to the python endpoint. What's great is the `proteinEntries` and `totalFound` have autocomplete types in typescript autogenerated from the backend!

See [`Protein.svelte`](../frontend/src/routes/Protein.svelte) for more concrete examples.

> [!IMPORTANT]
> On every change the a backend endpoint (response_model, name, endpoint) you will need to run `./run.sh gen_api` again to regenerate the frontend fetch wrapper functions

0 comments on commit ec572d2

Please sign in to comment.