Rails API for Go Bag (a packing list app)
Ruby HTML Shell

README.md

Go Bag API

A Rails API for Go Bag, a packing list app. Includes authentication. API is live at https://go-bag.herokuapp.com.

A detailed writeup of my development process is at rebekahheacock.org: Go Bag.

Dependencies

API Documentation

Scripts are included in scripts to test built-in actions.

Data Model

Go Bag Data Model

Authentication

Verb URI Pattern Controller#Action
POST /sign-up users#signup
POST /sign-in users#signin
PATCH /change-password/:id users#changepw
DELETE /sign-out/:id users#signout

POST /sign-up

Request:

curl --include --request POST http://localhost:3000/sign-up \
  --header "Content-Type: application/json" \
  --data '{
    "credentials": {
      "email": "an@example.email",
      "password": "an example password",
      "password_confirmation": "an example password"
    }
  }'
scripts/sign-up.sh

Response:

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
  "user": {
    "id": 1,
    "email": "an@example.email"
  }
}

POST /sign-in

Request:

curl --include --request POST http://localhost:3000/sign-in \
  --header "Content-Type: application/json" \
  --data '{
    "credentials": {
      "email": "an@example.email",
      "password": "an example password"
    }
  }'
scripts/sign-in.sh

Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "user": {
    "id": 1,
    "email": "an@example.email",
    "token": "33ad6372f795694b333ec5f329ebeaaa"
  }
}

PATCH /change-password/:id

Request:

curl --include --request PATCH http://localhost:3000/change-password/$ID \
  --header "Authorization: Token token=$TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "passwords": {
      "old": "an example password",
      "new": "super sekrit"
    }
  }'
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/change-password.sh

Response:

HTTP/1.1 204 No Content

DELETE /sign-out/:id

Request:

curl --include --request DELETE http://localhost:3000/sign-out/$ID \
  --header "Authorization: Token token=$TOKEN"
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/sign-out.sh

Response:

HTTP/1.1 204 No Content

Users

Verb URI Pattern Controller#Action
GET /users users#index
GET /users/1 users#show

GET /users

Request:

curl --include --request GET http://localhost:3000/users \
  --header "Authorization: Token token=$TOKEN"
TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/users.sh

Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "users": [
    {
      "id": 2,
      "email": "another@example.email"
    },
    {
      "id": 1,
      "email": "an@example.email"
    }
  ]
}

GET /users/:id

Request:

curl --include --request GET http://localhost:3000/users/$ID \
  --header "Authorization: Token token=$TOKEN"
ID=2 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/user.sh

Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "user": {
    "id": 2,
    "email": "another@example.email"
  }
}

Lists

Verb URI Pattern Controller#Action
GET /lists lists#index
GET /lists/1 lists#show
POST /lists lists#create
POST /clone/1 lists#clone
PATCH /lists/1 lists#update
DELETE /lists/1 lists#destroy

GET /lists

Users are only permitted to access their own lists.

Request:

curl --include --request GET http://localhost:3000/lists \
  --header "Authorization: Token token=$TOKEN"
TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/list-index.sh

Response:

HTTP/1.1 200 OK 
Content-Type: application/json; charset=utf-8

{
  "lists": [
    {
      "id":1,
      "title":"Kampala in January",
      "contents": []
    },
    {
      "id": 2,
      "title": "RightsCon 2016",
      "contents": []
    },

GET /lists/1

Users are only permitted to access their own lists.

Request:

curl --include --request GET http://localhost:3000/lists/$ID \
  --header "Authorization: Token token=$TOKEN"
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/list-show.sh

Response:

HTTP/1.1 200 OK 
Content-Type: application/json; charset=utf-8

{
  "list": {
    "id": 1,
    "title": "Kampala in January",
    "contents": []
  }
}

POST /lists

Request:

curl --include --request POST http://localhost:3000/lists \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{
    "list": {
      "title": "Camping"
    }
  }'
TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/list-create.sh

Response:

HTTP/1.1 201 Created 
Content-Type: application/json; charset=utf-8

{
  "list": {
    "id": 3,
    "title": "camping",
    "contents": []
  }
}

POST /clone/1

A POST request to /clone/:id clones the provided list with all of its associations. The cloned list's title will be "Copy of [original list's title]."

Request:

curl --include --request POST http://localhost:3000/clone/$ID \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{}'
ID=2 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/list-clone.sh

Response:

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
  "list": {
    "id": 4,
    "title": "Copy of camping",
    "contents": []
  }
}

PATCH /lists/1

Request:

curl --include --request PATCH http://localhost:3000/lists/$ID \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{
    "list": {
      "title": "Acadia Hiking"
    }
  }'
ID=4 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/list-update.sh

Response:

HTTP/1.1 204 No Content

DELETE /lists/1

Request:

curl --include --request DELETE http://localhost:3000/lists/$ID \
  --header "Authorization: Token token=$TOKEN"
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/list-destroy.sh

Response:

HTTP/1.1 204 No Content

Items

Verb URI Pattern Controller#Action
GET /items lists#index
GET /items/?query=j items#index
GET /items/1 lists#show
POST /items lists#create
PATCH /items/1 lists#update
DELETE /items/1 lists#destroy

GET /items

Request:

curl --include --request GET http://localhost:3000/items
scripts item-index.sh

Response:

HTTP/1.1 200 OK 
Content-Type: application/json; charset=utf-8

{
  "items": [
    {
      "id": 1,
      "name": "jacket"
    },
    {
      "id": 2,
      "name": "laptop"
    },
    {
      "id": 3,
      "name": "jeans"
    }
  ]
}

GET /items?query=j

Request:

curl --include --request GET http://localhost:3000/items?query=$QUERY
QUERY=j scripts/item-search.sh

Response:

HTTP/1.1 200 OK 
Content-Type: application/json; charset=utf-8

{
  "items": [
    {
      "id": 1,
      "name": "jacket"
    },
    {
      "id": 3,
      "name": "jeans"
    }
  ]
}

GET /items/1

Request:

curl --include --request GET http://localhost:3000/items/$ID
ID=1 scripts/item-show.sh

Response:

HTTP/1.1 200 OK 
Content-Type: application/json; charset=utf-8

{
  "item": {
    "id": 1,
    "name": "jacket"
  }
}

POST /items

Request:

curl --include --request POST http://localhost:3000/items \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{
    "item": {
      "name": "shirt"
    }
  }'
TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/item-create.sh

Response:

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
  "item": {
    "id": 4,
    "name": "shirt"
  }
}

PATCH /items/1

Request:

curl --include --request PATCH http://localhost:3000/items/$ID \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{
    "item": {
      "name": "power adapter"
    }
  }'
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/item-update.sh

Response:

HTTP/1.1 204 No Content

DELETE /items/1

Request:

curl --include --request DELETE http://localhost:3000/items/$ID \
  --header "Authorization: Token token=$TOKEN"
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/item-destroy.sh

Response:

HTTP/1.1 204 No Content

Contents

Verb URI Pattern Controller#Action
POST /contents contents#create
PATCH /contents/1 contents#update
DELETE /contents/1 contents#destroy

POST /contents

Request:

curl --include --request POST http://localhost:3000/contents \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{
    "content": {
      "item_id": "2",
      "list_id": "1",
      "packed": false
    }
  }'
TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/content-create.sh

Response:

HTTP/1.1 201 Created 
Content-Type: application/json; charset=utf-8

{
  "content": {
    "id": 1,
    "packed": false,
    "item": {
      "id":2,
      "name": "laptop",
      "created_at": "2016-10-01T16:30:25.224Z",
      "updated_at": "2016-10-01T16:30:25.224Z"
    },
    "list": {
      "id": 1,
      "title": "Kampala in January"
    }
  }
}

PATCH /contents/1

Request:

curl --include --request PATCH http://localhost:3000/contents/$ID \
  --header "Content-Type: application/json" \
  --header "Authorization: Token token=$TOKEN" \
  --data '{
    "content": {
      "packed": true
    }
  }'
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/content-patch.sh

Response:

HTTP/1.1 204 No Content

DELETE /contents/1

Request:

curl --include --request DELETE http://localhost:3000/contents/$ID \
  --header "Authorization: Token token=$TOKEN"
ID=1 TOKEN=33ad6372f795694b333ec5f329ebeaaa scripts/content-destroy.sh

Response:

HTTP/1.1 204 No Content

License

  1. All content is licensed under a CC­BY­NC­SA 4.0 license.
  2. All software code is licensed under GNU GPLv3.