# Writing new API Endpoints

### Security

<p class="callout danger">Important: All non-public routes **must** use type Session in the routes parameters! Otherwise, no login is required to access it!</p>

Minimal boilerplate:

```rust
#[get("/api/non/public/endpoint")]
pub async fn my_endpoint(
    _session: Session,
) -> Json<ApiResult<()>> {
  ApiResult::new_data(());
}
```

### Endpoints

Typically, you should implement GET, POST, DELETE and PATCH routes. POST routes are only used to create new objects, PATCH routes are used to update an existing object.

#### GET Route Example

Route to get a specific section in a project

```rust
/// GET /api/projects/<project_id>/sections/<content_path>?<expand>
///
/// Parameters:
/// * project_id (string) - the projects uuid
/// * content_path (string) - path to a specific section, split by ':'
/// * expand (string, optional) - optionally expand one of these fields: authors, editors, subsections
/// 
/// By default strips out subsections & only returns id's for authors and editors.
/// Use the optional expand query parameter to expand these fields
/// E.g. ?expand=authors,editors,subsections will show the full data
/// 
#[get("/api/projects/<project_id>/sections/<content_path>?<expand>")]
pub async fn get_section(
    project_id: &str,
    content_path: &str,
    expand: Option<&str>,
    _session: Session,
    settings: &State<Settings>,
    project_storage: &State<Arc<ProjectStorage>>,
    data_storage: &State<Arc<DataStorage>>
) -> Json<ApiResult<APISectionResult>> {
    ...
}
```

### Test your routes

You may test your new endpoints with curl. First, obtain a session cookie via your browser. Then use curl:

`curl -v --cookie 'session=INSERTYOURCOOKIEHERE' <host>/api/<route>`