An API to store data for a commercial kitchens for rent directory.
- Deployed On Heroku
- Checkout the Client-Repo
- Checkout the live Kitchn Listr App
- Initial ERD. This is what I would like my finished API to look like.
- Final ERD. This represents the current prototype.
Install with bundle install
.
- Fork and clone this repository.
- Install dependencies with
bundle install
. - Create a
.env
for sensitive settings (touch .env
). - Generate new
development
andtest
secrets (bundle exec rake secret
). - Store them in
.env
with keysSECRET_KEY_BASE_<DEVELOPMENT|TEST>
resepctively. - Run the API server with
bin/rails server
orbundle exec rake server
.
In order to make requests from your deployed client application, you will need
to set CLIENT_ORIGIN
in the environment (e.g. heroku config:set CLIENT_ORIGIN=https://<github-username>.github.io
).
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 | /kitchens |
kitchens#create |
GET | /kitchens |
kitchens#index |
GET | /kitchens/:id |
kitchens#show |
PATCH | /kitchens/:id |
kitchens#update |
DELETE | /kitchens/:id |
kitchens#destroy |
GET | /userskitchen |
kitchens#userskitchen |
The create
action expects a POST of credentials
and user
information identifying a new user and to create, in this case using getFormFields
:
<form>
<input name="credentials[email]" type="text" value="a@example.email">
<input name="credentials[password]" type="password" value="an example password">
<input name="credentials[password_confirmation]" type="password" value="an example password">
</form>
Request:
curl http://localhost:4741/sign-up \
--include \
--request POST \
--header "Content-Type: application/json" \
--data '{
"credentials": {
"email": "'"${EMAIL}"'",
"password": "'"${PASSWORD}"'",
"password_confirmation": "'"${PASSWORD}"'"
}'
EMAIL=A@A.com PASSWORD=Ash scripts/sign-in.sh
Response:
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
{
"user": {
"id": 1,
"email": "A@A.com"
}
}
Request:
curl http://localhost:4741/sign-in \
--include \
--request POST \
--header "Content-Type: application/json" \
--data '{
"credentials": {
"email": "'"${EMAIL}"'",
"password": "'"${PASSWORD}"'"
}
}'
EMAIL=A@A.com PASSWORD=Ash scripts/sign-in.sh
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"user": {
"id": 1,
"email": "A@A.com",
"token": "BAhJIiUyNjA2Y2EwYjIzYzU4OGQ5ZDdhY2YwZThlOGM2MzFhMAY6BkVG--9b4e60909025d8db3a9e3cf9fa156d0a851ba2e4"
}
}
Request:
curl --include --request PATCH "http://localhost:4741/change-password/$ID" \
--header "Authorization: Token token=$TOKEN" \
--header "Content-Type: application/json" \
--data '{
"passwords": {
"old": "'"${OLDPW}"'",
"new": "'"${NEWPW}"'"
}
}'
TOKEN=BAhJIiUyNjA2Y2EwYjIzYzU4OGQ5ZDdhY2YwZThlOGM2MzFhMAY6BkVG--9b4e60909025d8db3a9e3cf9fa156d0a851ba2e4 scripts/change-password.sh
Response:
HTTP/1.1 204 No Content
Request:
curl http://localhost:4741/sign-out/$ID \
--include \
--request DELETE \
--header "Authorization: Token token=$TOKEN"
ID=1 TOKEN=BAhJIiUyNjA2Y2EwYjIzYzU4OGQ5ZDdhY2YwZThlOGM2MzFhMAY6BkVG--9b4e60909025d8db3a9e3cf9fa156d0a851ba2e4 ID=1 scripts/sign-out.sh
Response:
HTTP/1.1 204 No Content
Verb | URI Pattern | Controller#Action |
---|---|---|
GET | /users |
users#index |
GET | /users/1 |
users#show |
Request:
curl http://localhost:4741/users \
--include \
--request GET \
--header "Authorization: Token token=$TOKEN"
TOKEN=BAhJIiUyNjA2Y2EwYjIzYzU4OGQ5ZDdhY2YwZThlOGM2MzFhMAY6BkVG--9b4e60909025d8db3a9e3cf9fa156d0a851ba2e4 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": "A@A.com"
}
]
}
Request:
curl --include --request GET http://localhost:4741/users/$ID \
--header "Authorization: Token token=$TOKEN"
ID=2 TOKEN=BAhJIiUyNjA2Y2EwYjIzYzU4OGQ5ZDdhY2YwZThlOGM2MzFhMAY6BkVG--9b4e60909025d8db3a9e3cf9fa156d0a851ba2e4 scripts/users.sh
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"user": {
"id": 2,
"email": "another@example.email"
}
}
All Kkitchen action requests must include a valid HTTP header Authorization: Token token=<token>
or they will be rejected with a status of 401 Unauthorized.
This is not a task developers should run often, but it is sometimes necessary.
locally
bin/rake db:migrate VERSION=0
bin/rake db:migrate db:seed db:examples
heroku
heroku run rake db:migrate VERSION=0
heroku run rake db:migrate db:seed db:examples
Developers should run these often!
bin/rake routes
lists the endpoints available in your API.bin/rake test
runs automated tests.bin/rails console
opens a REPL that pre-loads the API.bin/rails db
opens your database client and loads the correct database.bin/rails server
starts the API.scripts/*.sh
run variouscurl
commands to test the API. See below.
- Ruby
- Ruby on Rails
- PostgreSQL
When I started this project I thought it was going to be easier that it turned out.
I wanted to make profiles for user when they sign up so that we could determine what data to
allow them to access based on the user's role
. I didn't want to create 2 models for that
since the user's profile shared all the same attributes except their role. ne was either a kitchen
owner the other a chef.
This was hardest to implement. I started out trying to do polymorphic associations, then I tried
to do ActiveRecord::Enum. For the most part I could CRUD on profiles but by the time it got to
linking the profile model and the kitchen model it was hard for me to edit the controller to represent the
data I wanted it to. After a few days of this I abbandoned the feature to come back to it at a later time.
Another thing that I struggled with was showing a user only the kitchens they created, I solved this
problem by creating a new route \userskitchen
.
I learned how important it is to descope and timebox myself after working on profiles issue for more than 2 days.
I have many unfinished features that I will be working on implementing like: Features:
- CRUD for Review (create, read, update, delete)
- Image uploads
- Store assets to AWS
- Owner access reviews on their kitchen
- Star reviews
Data Models Profile belongs_to :user
- givenName | string
- surname | string
- Role | Owner:string , Chef:string
- Phone number: integer
Equipment belongs_to :kitchen
- rubber_floor_mats
- fire_extinguisher
- freezer:boolean
- ovens:boolean
- refrigirator:boolean
- food_prep_counter:boolean slicers:boolean mixers:boolean
- food_processors:boolean ranges:boolean
- sinks:boolean shelving:boolean storage:boolean safety_equipment:boolean
- Metal or plastic shelves for walk-in cooler
Reviews belongs_to :profile has_many_through :kitchens
- Rating -- Star (Boolean?)
- comments: string