Skip to content

Commit

Permalink
continue refactoring, update README.md format
Browse files Browse the repository at this point in the history
  • Loading branch information
philangist committed May 6, 2018
1 parent fa38b33 commit bfea26f
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 145 deletions.
103 changes: 43 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
API
### Asset Picker API

Introduction: A suite of resource representations and their corresponding
endpoints for traversing the frame.io asset storage backend
__Introduction:__
A suite of resource representations and their corresponding endpoints for traversing the frame.io asset storage backend

Assumptions: There is an invariant we assume holds here, that every project
has exactly one root folder associated with it. This should be
enforced in the api layer code through the POST, PUT, and DELETE
verbs for both projects/ and assets/, and also possibly as a DB
level constraint on the assets table.
We also assume that all assets with type != 1 are leaves in the
project tree.
Assumptions: There is an invariant we assume holds here, that every project has exactly one root folder associated with it. This should be enforced in the api layer code through the POST, PUT, and DELETE verbs for both projects/ and assets/, and also possibly as a DB level constraint on the assets table

Meta/Pagination: TODO: FILL THIS WHEN I DECIDE IF/HOW TO IMPLEMENT PAGINATION
We also assume that all assets with type != 1 are leaves in the project tree

Projects
__Meta/Pagination:__
TODO: FILL THIS WHEN I DECIDE IF/HOW TO IMPLEMENT PAGINATION

- Projects are the high-level structures users to store their video and other
media assets. All of their content is organized within a "project", and within
each project files can be infinitely nested within folders.
### Projects:

Endpoints:
GET projects/ - list all projects in the database
- Projects are the high-level structures users to store their video and other media assets. All of their content is organized within a "project", and within each project files can be infinitely nested within folders.

response:
status code: 200 OK
```json
__Endpoints:__
`GET /projects/` - list all projects in the database

response:
status code: 200 OK
```javascript
{
data: [
{
Expand All @@ -42,11 +37,11 @@ status code: 200 OK
}
```

GET projects/:id - retrieve a specific project by id
`GET /projects/:id` - retrieve a specific project by id

response:
status code: 200 OK
```json
response:
status code: 200 OK
```javascript
{
id: int,
name: string (128),
Expand All @@ -55,39 +50,27 @@ status code: 200 OK
}
```

Assets
### Assets

- Assets are the mechanism used to both refer to the media objects we're
actually storing as well as express their heirarchical relationship with
each other. Take note that for every project there must exist exactly one
asset with type=folder, parent_id=null, and project_id=project.id.
Also take note that it is a logical contradiction for an asset to have a
parent asset of type > 1.
- Assets are the mechanism used to both refer to the media objects we're actually storing as well as express their heirarchical relationship with each other. Take note that for every project there must exist exactly one asset with `type='folder'`, `parent_id=null`, and `project_id=project.id`. Also take note that it is a logical contradiction for an asset to have a parent asset of type > 1.

Endpoints:
GET assets/ - list all assets in the database
__Endpoints:__
`GET /assets/` - list all assets in the database

response:
status code: 200 OK
```json
response:
status code: 200 OK
```javascript
{
data: [
{
id: int
name: string (128)
parent_id: int // references a parent asset with type=folder.
// nullable only for type=folder objects
media_url: string (variable length, typically between 84
- 100 characters), // physical location of the
// media object associated
// with this asset. format is a http url of type
// "http://<env>.frame.io/asset_sha256_hash". possible values of
// env are dev, qa-<cluster_id> and cdn
type: int media object type // current possible values are int(1)
// for folders and (2) for video files
project_id: int // references the encapsulating project which
// this asset belongs to. there must exist exactly one asset of
// type=folder and parent_id=null for every project in the database
media_url: string (variable length, typically between 84 - 100 characters), // physical location of the
// media object associated with this asset. format is a http url of type "http://<env>.frame.io/asset_sha256_hash". possible values of env are dev, qa-<cluster_id> and cdn
type: int media object type // current possible values are int(1) for folders and (2) for video files
project_id: int // references the encapsulating project which this asset belongs to. there must exist exactly one asset of type=folder and parent_id=null for every project in the database
created_at: timestamp // asset creation date
},
..
Expand All @@ -97,18 +80,18 @@ status code: 200 OK
}
}
```
supported query parameters:
type int - filter assets by type identifier
project\_id int - filter assets by project identifier
parent\_id int - filter assets by parent_identifier
expand bool - returns all children of any assets that are returned by
any combination of the above query parameters

GET assets/:id retrieve a specific asset by id

response:
status code: 200 OK
```json
supported query parameters:
`type` int - filter assets by type identifier
`project\_id` int - filter assets by project identifier
`parent\_id` int - filter assets by parent identifier
`expand` bool - returns all children of any assets that are returned by
any combination of the above query parameters

`GET assets/:id` retrieve a specific asset by id

response:
status code: 200 OK
```javascript
{
id: int
name: string (128)
Expand All @@ -118,4 +101,4 @@ status code: 200 OK
project_id: int
created_at: timestamp
}
```
```
4 changes: 2 additions & 2 deletions controllers/assets.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package controllers

import (
"log"
"net/http"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -71,7 +70,8 @@ func AssetsQueryController(w http.ResponseWriter, r *http.Request) {
limit,
)
if err != nil {
log.Panic(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

serializedAssets, err := assets.Serialize()
Expand Down
4 changes: 2 additions & 2 deletions controllers/projects.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package controllers

import (
"log"
"net/http"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -49,7 +48,8 @@ func ProjectsQueryController(w http.ResponseWriter, r *http.Request) {

projects, err := ProjectsGet(models.IGNORE, offset, limit)
if err != nil {
log.Panic(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

serializedProjects, err := projects.Serialize()
Expand Down
3 changes: 0 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"fmt"
"log"
"net/http"

Expand All @@ -10,8 +9,6 @@ import (
)

func main() {
fmt.Println("Hej, Världen!")

router := mux.NewRouter()

// routers for /projects resource
Expand Down
20 changes: 11 additions & 9 deletions models/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"time"
)

var DOMAIN_ROOT = "http://dev.frame.io"

// EntityManager
type AssetsManager struct {
DBConfig *DBConfig
Expand Down Expand Up @@ -41,7 +43,7 @@ func (am *AssetsManager) Execute(query *AssetsQuery) (*Assets, error) {

var rows *sql.Rows
queryString, values := query.Build()
log.Printf("query is %s values are %v", queryString, values)

if len(values) == 0 {
rows, err = db.Query(queryString)
} else {
Expand Down Expand Up @@ -134,7 +136,7 @@ func NewAssetsQuery(
return nil, err
}

if descendants != "" {
if descendants != IGNORE {
descendantsBool, err = strconv.ParseBool(descendants)
if err != nil {
return nil, err
Expand Down Expand Up @@ -252,7 +254,7 @@ func (aq *AssetsQuery) Build() (string, []interface{}) {
if aq.Descendants {
descendantsQuery := `
WITH ancestor_nodes AS (
{ORIGINAL_QUERY}
{BASE_QUERY}
)
SELECT assets.id, assets.name, assets.parent_id, assets.media_url, assets.category,
assets.project_id, assets.created_at
Expand All @@ -262,7 +264,7 @@ WHERE assets.id IN
OR assets.parent_id IN
(SELECT ID FROM ancestor_nodes)
`
replacer := strings.NewReplacer("{ORIGINAL_QUERY}", query)
replacer := strings.NewReplacer("{BASE_QUERY}", query)
query = replacer.Replace(descendantsQuery)
}

Expand All @@ -281,6 +283,10 @@ func NewAssets(assets []*SerializableAsset, total int, limit, offset int64) *Ass
return &Assets{assets, page}
}

func (a *Assets) Serialize() ([]byte, error) {
return json.Marshal(a)
}

type Asset struct {
ID int
Name string
Expand Down Expand Up @@ -316,7 +322,7 @@ func NewSerializableAsset(a *Asset) *SerializableAsset {

if a.MediaURL.Valid {
mediaURL = fmt.Sprintf(
"http://dev.frame.io/%s", a.MediaURL.String)
"%s/%s", DOMAIN_ROOT, a.MediaURL.String)
}

return &SerializableAsset{
Expand All @@ -329,7 +335,3 @@ func NewSerializableAsset(a *Asset) *SerializableAsset {
CreatedAt: a.CreatedAt,
}
}

func (a *Assets) Serialize() ([]byte, error) {
return json.Marshal(a)
}
4 changes: 2 additions & 2 deletions models/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (pm *ProjectsManager) Execute(query *ProjectsQuery) (*Projects, error) {

var rows *sql.Rows
queryString, values := query.Build()
log.Printf("query is %s values are %v", queryString, values)

if len(values) == 0 {
rows, err = db.Query(queryString)
} else {
Expand Down Expand Up @@ -96,7 +96,7 @@ func NewProjectsQuery(id, offset, limit string) (*ProjectsQuery, error) {
var id64, offset64, limit64 int64
var err error

if id == "" {
if id == IGNORE {
offset64, err = CoerceToInt64(offset)
if err != nil {
return nil, err
Expand Down
66 changes: 0 additions & 66 deletions models/projects_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion sql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ INSERT INTO assets(id, name, parent_id, media_url, category, project_id) VALUES
(2, 'P1F1/File 1', 1, 'long_sha256_hash_here', 2, 1),
(3, 'P1F1/File 2', 1, 'long_sha256_hash_here', 2, 1),
(4, 'Project 1 Folder 1/Subfolder 1', 1, NULL, 1, 1),
(5, 'P1F1/F1/S1/File 1', 5, 'long_sha256_hash_here', 2, 1),
(5, 'P1F1/F1/S1/File 1', 4, 'long_sha256_hash_here', 2, 1),
(6, 'Project 2 Folder 1', NULL, NULL, 1, 2);
COMMIT;

0 comments on commit bfea26f

Please sign in to comment.