aboutsummaryrefslogtreecommitdiffstats
path: root/rust/HACKING.md
blob: 6a89f16916daa7b95bb93f99107c6d4fef903778 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

## Code Structure

Almost all of the rust code is either auto-generated or "glue" between the
swagger API spec on one side and the SQL schema on the other.

- `./migrations/*/up.sql`: SQL schema
- `./src/database_schema.rs`: autogenerated per-table Diesel schemas
- `./src/database_models.rs`: hand- and macro-generated Rust structs matching
  Diesel schemas, and a small number of row-level helpers
- `./src/entity_crud.rs`: "struct-relational-mapping"; trait
  implementations of CRUD (create, read, update, delete) actions for each
  entity model, hitting the database (and building on `database_model` structs)
- `./src/endpoint_handlers.rs`: one function for each API endpoint, with rust-style
  arguments and return types. mostly calls in to `api_entity_crud`.
- `./src/endpoints.rs`: hand- and macro-generated wrapper functions, one per
  API endpoint, that map between API request and return types, and
  rust-idiomatic request and return types (plus API models).
- `./fatcat-openapi`: autogenerated API models and endpoint types/signatures
- `../fatcat-openapi2.yaml`: OpenAPI 2 specification of API models and
  endpoints

When deciding to use this structure, it wasn't expected that either
`api_wrappers.rs` or `database_models.rs` would need to hand-maintained; both
are verbose and implemented in a very mechanical fashion. The return type
mapping in `api_wrappers` might be necessary, but `database_models.rs` in
particular feels unnecessary; other projects have attempted to completely
automate generation of this file, but it doesn't sound reliable. In particular,
both regular "Row" (queryable) and "NewRow" (insertable) structs need to be
defined.

## Test Structure

- `./tests/test_api_server.rs`: Iron (web framework) level raw HTTP JSON
  request/response tests of API endpoints.

## Updating Schemas

Regenerate API schemas after editing the fatcat-openapi2 schema. This will, as
a side-effect, also run `cargo fmt` on the whole project, so don't run it with
your editor open!

    cargo install cargo-swagger  # uses docker
    ./codegen_openapi2.sh

Update Rust database schema (after changing raw SQL schema):

    diesel database reset
    diesel print-schema > src/database_schema.rs

Debug SQL schema errors (if diesel commands fail):

    psql fatcat_dev < migrations/2019-01-01-000000_init/up.sql

## Direct API Interaction

First setup an auth token and check that authentication is working

    EDITOR_ID='aaaaaaaaaaaabkvkaaaaaaaaay'
    AUTH_TOKEN=`./target/debug/fatcat-auth create-token $EDITOR_ID`
    http get :9411/v0/auth/check "Authorization:Bearer $AUTH_TOKEN"
    http get :9411/v0/auth/check?role=admin "Authorization:Bearer $AUTH_TOKEN"

You'll need to add the `$AUTH_TOKEN` bit to all requests below.
    
Creating entities via API:

    http --json post localhost:9411/v0/container name=asdf issn=1234-5678

## Authentication

Uses macaroons. See `notes/auth.md` and maybe look in the guide.

## Codegen Updates

These are notes from another branch?

### OpenAPI Generator 5.0

    export OPENAPI_GENERATOR_VERSION=5.0.0-SNAPSHOT
    ./openapi-generator-cli.sh version

### OpenAPI Standard 3.0

Should consider doing this conversion by hand, not using converter tool.

Motivation to make this change for CLI was that rust-server doesn't support
client Bearer authentication from OpenAPI 2.0.

Request bodies now don't have a "name", so the parameter ends up being infered
from the type. For auto_batch, this means "auto_batch_fileset" or whatever
instead of "auto_batch".