yata-server

Development

One Time Setup

AWS Config

The yata server needs AWS credentials in order to call various AWS services as part of normal operation. Create an IAM user in your AWS account with administrative access and then create a profile called "yata" locally with aws configure --profile yata. See the "Advanced Configuration" section to customize the profile name.

Setting Cognito config

The yata server uses Cognito to authenticate requests.

  1. Create a new Cognito user pool in your AWS account.
    1. Under the "General settings" navigation select "App clients" and create an app client. Make note of the app client id.
    2. Under the "App integration" navigation
      1. Select "App client settings", locate the app client you created earlier:
        1. Check "Cognito User Pool" under "Enabled Identity Providers"
        2. Enter http://localhost:8888 as the Callback URL(s).
        3. Check "Implicit grant" under "Allowed OAuth Flows".
        4. Check "openid" under "Allowed OAuth Scopes".
        5. Click save; the "Launch Hosted UI" link should now be available, click it.
      2. Select "Domain name" and give your user pool a domain prefix. Make note of the domain name.
  2. Copy the file in env/SampleConfig.json to env/CognitoConfig.json and modify it to suite your setup.

See the "Advanced Configuration" section to customize the filename.

Creating a Cognito User

To use meaningfully interact with the server you need to authenticate. To authenticate you need a user to login in with.

  1. Go back to the "App client settings" page of your Cognito user pool.
  2. Locate the "Launch Hosted UI" link; click it.
  3. Click the "Sign Up" link at the bottom of the UI.
  4. Enter a desired username, email, and password.
  5. Complete email-based verification.

into Using the domain name you noted earlier go to the following URL to view your Cognito hosted UI to create a user.

https://<your_domain>/login?response_type=token&client_id=<your_app_client_id>&redirect_uri=<your_callback_url>

Creating DynamoDB Tables

The server uses DynamoDB tables to store items and lists. You can either create them by deploying https://github.com/TheYeung1/yata-infrastructure or creating them manually:

  1. Create a table called ListTable.
    1. With a partition key called UserID that's a String.
    2. With a sort key called ListID that's a String.
    3. Uncheck Use default settings and change the table to use On-demand capacity mode. Leave all other settings untouched.
  2. Create a table called ListTable.
    1. With a partition key called UserID that's a String.
    2. With a sort key called ListID-ItemID that's a String.
    3. Uncheck Use default settings and change the table to use On-demand capacity mode. Leave all other settings untouched.

See the "Advanced Configuration" section to customize the table names.

Everyday

Getting a JWT token

  1. Go back to the "App client settings" page of your Cognito user pool.
  2. Locate the "Launch Hosted UI" link; click it.
  3. Login in with the user you created earlier.
  4. You will be redirected back to the following URL:
    http://localhost:8888/#id_token=TOKEN&access_token=TOKEN&expires_in=3600&token_type=Bearer
    
  5. Copy the TOKEN to your clipboard.

Running the Server

  1. go run main.go
  2. The server will start and be available at http://localhost:8888.

Hitting an API Endpoint

export TOKEN=<TOKEN>
curl -H "Authorization: Bearer $TOKEN" http://localhost:8888/items

Where the <TOKEN> is the same TOKEN you retrieved when getting the JWT token earlier.

Examples

Listing all your items

curl -H "Authorization: Bearer $TOKEN" http://localhost:8888/items

Listing all your lists

curl -H "Authorization: Bearer $TOKEN" http://localhost:8888/lists

Getting a list

curl -H "Authorization: Bearer $TOKEN" http://localhost:8888/lists/<listID>/

Creating a list

curl -X PUT -d '{"ListID":"ID1","Title":"My First List"}' -H "Authorization: Bearer $TOKEN" http://localhost:8888/lists

Adding an item to a list

curl -X PUT -d '{"ItemID":"ID1","Content":"My First Item"}' -H "Authorization: Bearer $TOKEN" http://localhost:8888/lists/<listID>/items

Listing the items on a list

curl -H "Authorization: Bearer $TOKEN" http://localhost:8888/lists/<listID>/items

Advanced Configuration

The yata server uses a series of optional command line flags to configure itself. Run go run main.go --help to view these flags and their default values.

Contributing

  1. (one time) Fork this repo.
  2. Pull down the latest: git pull origin.
  3. Checkout a new branch for your change with git checkout -b <name>. The <name> should be prefixed with one of ["feat", "chore", "bugfix", "other"]. Examples:
    1. feat-add-logging.
    2. chore-cleanup-feature-gate.
    3. bugfix-handle-malformed-requests.
    4. other-do-something-interesting.
  4. Make your change. Reference the Style Guide below to ensure your changes are consistent.
  5. Add tests (optional but strongly suggested).
  6. Test your change.
  7. Run make to format, vet, test, and build your changes. Make sure this passes.
  8. Push to your fork.
  9. Create a pull request.
  10. Get your changes merged in.
  11. Checkout the main branch (git checkout main) and pull (git pull origin) down the latest.
  12. Delete your new branch:
    1. Locally: git branch -d <name>.
    2. Remotely: git push <fork name> --delete <name>.
  13. Update your fork: git push <fork name>.

Style Guide

  1. Code should be formatted with make fmt.
  2. Code should be vetted with make vet.
  3. %q is preferred over %s when printing strings.
  4. Imports should be sorted into two groups: standard library and everything else.
  5. When logging an error use .WithError(err) and a helpful error message. Ex: log.WithError(err).Error("failed to foo the bars").
  6. Error messages should start with a lowercase letter. Ex: failed to foo not Failed to foo.
  7. Use PascalCase or camelCase over other casings such as snake_case or kebab-case.

TODO

Things we need to do. In no real order. Not comprehensive.

  1. More unit tests.
  2. Using a request-specific logger.
  3. How do we deploy this thing?