Code Monkey home page Code Monkey logo

pedestal-ions-sample's Introduction

Pet store service

A simple pet store service implemented as a Datomic Ion using the pedestal.ions chain provider. Consumes and emits JSON and supports CRUD operation on Pet resources.

Demonstrates:

  • Ionizing a Pedestal service.
  • Using Ion Parameters.
  • Transacting schema.
  • Running the service locally via Jetty.

Prerequisites

  • You have an AWS account with sufficient privileges which you can use to provision Datomic Cloud. If you don't have an AWS account, refer to the AWS documentation for instructions on how to set one up. Note: Running this sample will incur AWS charges. The cost of running Datomic Cloud's Solo topology is approximately $1/day.
  • You have AWS credentials provisioned locally. Refer to the AWS documentation for details on how to set up credentials.

Getting Started

Provisioning and configuring Datomic Cloud

Follow the Datomic Cloud Setting Up guide to provision your Datomic Cloud environment. Be sure to choose the Solo Fulfillment option. This sample assumes the _Stack Name is ion-pet-service.

Once your Datomic Cloud environment is provisioned, continue on to the Configuring Access documentation and, finally, the Getting Started guide.

Local Development

You will need to export the following environment variables in order to run this sample locally:

  • AWS_PROFILE: The AWS profile in your AWS credentials file.
  • AWS_REGION: The AWS region in which you have provisioned Datomic Cloud.
  • DATOMIC_ENV_MAP: See below.
  • DATOMIC_APP_INFO_MAP: See below.

The Datomic Ion param environment variables should be set as follows:

export DATOMIC_ENV_MAP="{:env :dev}""
export DATOMIC_APP_INFO_MAP="{:app-name \"ion-pet-service\" :deployment-group \"$DeploymentGroup\"}"

Where $DeploymentGroup is the name of your Ion deployment group (see Ion Deploy).

Parameters

Pedestal Ions provides access to Datomic Ion parameters. Refer to the README for details.

The values of the :io.pedestal.ions/app-info and :io.pedestal.ions/env-map keys are pulled from their respective Datomic Ion param environment variables which were specified in the Local Development section of this guide.

To run this sample, you will need to create a db-name parameter in AWS Systems Manager Parameter Store. This can be done as follows:

aws ssm put-parameter --name /datomic-shared/dev/ion-pet-service/db-name --value pet-store --type String

Deployment

To push the project to your Datomic Cloud environment, execute the following command from the root directory of the sample project:

clojure -A:dev -m datomic.ion.dev '{:op :push"}'

You will need to add a :uname key if you have made changes to the sample and they have not been committed to Git.

This command will return a map containing the key :deploy-command. Copy the value and execute it at the command line to deploy the ionized app. You will need to unescape the :uname value.

The deployment command returns a map as well. This map contains the key :status-command. Copy the value of this key and execute it on the command line to track the status of the deployment. After a few seconds you should see a successful result that looks like this:

{:deploy-status "SUCCEEDED", :code-deploy-status "SUCCEEDED"}

Provisioning API Gateway

  • Go to the AWS API Gateway console to create a new AWS API Gateway for this sample.
  • Choose New API from the Create new API options.
  • Name your API pet-service.
  • Click Create API.
  • Under the Actions dropdown, choose Create Resource.
  • Check the box Configure as proxy resource.
  • Click Create Resource.

To connect the API to the deployed pet service ion:

  • Select the ANY method under /{proxy+}.
  • Leave the Integration type as Lambda Function Proxy.
  • Set the Lambda Function to ion-pet-service-${Group}-app, where $Group is your Datomic Cloud compute group.
  • Click Save.
  • Choose Ok to give your API Gateway permission to call your lambda.
  • Under your API in the left side of the UI, click on the bottom choice Settings.
  • Choose Add Binary Media Type, add the */* type.
  • Click Save Changes.

To deploy your API:

  • Click on your API name and choose Deploy API under the Actions dropdown.
  • Choose New Stage as the Deployment Stage, add the stage dev, then choose Deploy.

The top of the Stage Editor will show the url for your app.

Your API is now deployed. Keep in mind that it is public. Be sure to remove it when done using it!

Interacting with the deployed app.

The commands that follow expect that you replace $INVOKE_URL with the Invoke URL of your deployed api.

Retrieving pets

curl -X GET https://$INVOKE_URL/dev/pets

You should see the following result:

[
    {
        "pet-store.pet/id": 2,
        "pet-store.pet/name": "Dante",
        "pet-store.pet/tag": "cat"
    },
    {
        "pet-store.pet/id": 1,
        "pet-store.pet/name": "Yogi",
        "pet-store.pet/tag": "dog"
    }
]

Add a pet

curl -X POST \
  https://$INVOKE_URL/dev/pets \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '    {
        "id": 302,
        "name": "Foobar",
        "tag": "bird"
    }'

Which should return a 201: Created.

Perform another GET of /pets will include the new pet.

curl -X GET https://$INVOKE_URL/dev/pets
[
    {
        "pet-store.pet/id": 2,
        "pet-store.pet/name": "Dante",
        "pet-store.pet/tag": "cat"
    },
    {
        "pet-store.pet/id": 302,
        "pet-store.pet/name": "Foobar",
        "pet-store.pet/tag": "bird"
    },
    {
        "pet-store.pet/id": 1,
        "pet-store.pet/name": "Yogi",
        "pet-store.pet/tag": "dog"
    }
]

Put a Pet

Update the petFoobar:

curl -X PUT \
  https://$INVOKE_URL/dev/pet/302 \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '    {
        "name": "Foox",
        "tag": "bird"
    }'

The updated pet will be returned:

{
    "pet-store.pet/id": 302,
    "pet-store.pet/name": "Foox",
    "pet-store.pet/tag": "Bird"
}

Delete a pet

Now remove the pet Foox:

curl -X DELETE \
  https://$INVOKE_URL/dev/pet/302 \
  -H 'Cache-Control: no-cache'

A response with the HTTP status 204: No content will be returned.

Connecting to Datomic Cloud from a local repl

Start the SOCKS proxy as per the Datomic Cloud docs.

Start a repl and connect to it:

$  clj -Adev:log

Instantiate a handler so you can interact with the app:

user=> (require '[ion-provider.ion :as ion]
                '[ion-provider.service :as service])

user=> (def h (ion/handler service/service))

Make some requests:

user=> (h {:server-port    0
           :server-name    "localhost"
           :remote-addr    "127.0.0.1"
           :uri            "/"
           :scheme         "http"
           :request-method :get
           :headers        {}})

INFO  io.pedestal.http  - {:msg "GET /", :line 80}
{:status 200, :headers {"Strict-Transport-Security" "max-age=31536000; includeSubdomains", "X-Frame-Options" "DENY", "X-Content-Type-Options" "nosniff", "X-XSS-Protection" "1; mode=block", "X-Download-Options" "noopen", "X-Permitted-Cross-Domain-Policies" "none", "Content-Security-Policy" "object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;", "Content-Type" "text/plain"}, :body "Hello World!"}

user=> (slurp (:body (h {:server-port    0
               :server-name    "localhost"
               :remote-addr    "127.0.0.1"
               :uri            "/pets"
               :scheme         "http"
               :request-method :get})))

INFO  io.pedestal.http  - {:msg "GET /pets", :line 80}
...
"[{\"pet-store.pet/id\":2,\"pet-store.pet/name\":\"Dante\",\"pet-store.pet/tag\":\"cat\"},{\"pet-store.pet/id\":1,\"pet-store.pet/name\":\"Yogi\",\"pet-store.pet/tag\":\"dog\"}]"

Hosting the service locally

You may prefer interacting with a locally running service instead of the ion handler. You can do so by configuring the service to use jetty instead of the ion chain provider. The ion-sample.server namespace demonstrates this. Keep in mind that you still need to have the Datomic SOCKS proxy running to access Datomic Cloud!

The ion-sample.server source is found in the dev source directory. To include it and the pedestal.jetty dependency, start up a repl with the :jetty alias appended as follows:

$ clj -Adev:log:jetty

Then startup a server:

user=> (require '[ion-sample.server :as server])
user=> (def pet-service (server/run-dev 9091))

You can now interact with your server via curl:

$ curl -X GET http://localhost:9091/pets

which returns:

[{"pet-store.pet/id":2,"pet-store.pet/name":"Dante","pet-store.pet/tag":"cat"},{"pet-store.pet/id":1,"pet-store.pet/name":"Yogi","pet-store.pet/tag":"dog"}]%

Once you are done interacting with the service, you can stop it as follows:

$ (server/stop pet-service)

Cleanup

Follow the Datomic Cloud Deleting a System guide for instructions on removing the provisioned resources.

Delete the policy Datomic-ion-pet-service-{REGION}

Delete the CodeDeploy project ion-pet-service.


License

Copyright 2018 Cognitect, Inc.

The use and distribution terms for this software are covered by the Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0) which can be found in the file epl-v10.html at the root of this distribution.

By using this software in any fashion, you are agreeing to be bound by the terms of this license.

You must not remove this notice, or any other, from this software.

pedestal-ions-sample's People

Contributors

ddeaguiar avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.