cognitect-labs / vase

Data driven microservices
Eclipse Public License 1.0
375 stars 41 forks source link

Post is not creating new entities #27

Closed nottmey closed 7 years ago

nottmey commented 7 years ago

Description

I followed the Tutorial "Building your first API" to "Getting data in with transact", but I can't get :post to be transacting the new entity. It boils down to the following problem.

My minimal EDN:

{:activated-apis
 [:accounts/v1]

 :datomic-uri
 "datomic:free://localhost:4334/example" ;; or "datomic:mem://example", same response

 :descriptor
 {:vase/norms
  {:accounts/user
   {:vase.norm/txes [#vase/schema-tx
       [[:user/userId :one :string :unique "The unique identifier for a user"]
        [:user/email :one :string :unique "The email address for a given user"]]]}}

  :vase/specs
  {}

  :vase/apis
  {:accounts/v1
   {:vase.api/routes
    {"/user" {:post #vase/transact {:name       :accounts.v1/user-create
                                    :properties [:db/id :user/userId :user/email]}}}

    :vase.api/schemas
    [:accounts/user]

    :vase.api/forward-headers
    ["vaserequest-id"]}}}}

Request-Variations: (same response)

curl --form user/userId=42 --form user/email=user@example.com http://localhost:8080/api/accounts/v1/user
curl --form :user/userId=42 --form :user/email=user@example.com http://localhost:8080/api/accounts/v1/user

curl -H "Content-Type: application/json" -X POST -d '{"user/userId":"42","user/email":"user@example.com"}' http://localhost:8080/api/accounts/v1/user
curl -H "Content-Type: application/json" -X POST -d '{":user/userId":"42",":user/email":"user@example.com"}' http://localhost:8080/api/accounts/v1/user

(also tried same requests in postman, same results)

Response:

{"whitelist":[],"transaction":[[null,null,null],[null,null,null],[null,null,null],[null,null,null]]}

Log: (for one request)

INFO  io.pedestal.http - {:msg "POST /api/accounts/v1/user", :line 78}
INFO  io.pedestal.http.cors - {:msg "cors request processing", :origin "", :allowed true, :line 84}
INFO  datomic.kv-cluster - {:event :kv-cluster/get-pod, :pod-key "pod-catalog", :phase :begin, :pid 96750, :tid 70}
INFO  datomic.kv-cluster - {:event :kv-cluster/get-pod, :pod-key "pod-catalog", :msec 1.08, :phase :end, :pid 96750, :tid 70}
INFO  datomic.peer - {:event :peer/transact, :uuid #uuid "5895a3de-ff72-49a5-a318-f1d45ad8ad66", :phase :start, :pid 96750, :tid 85}
INFO  datomic.peer - {:event :peer/transact, :uuid #uuid "5895a3de-ff72-49a5-a318-f1d45ad8ad66", :phase :end, :pid 96750, :tid 52}
INFO  datomic.peer - {:event :peer/notify-data, :msec 1, :id #uuid "5895a3de-ff72-49a5-a318-f1d45ad8ad66", :pid 96750, :tid 52}
INFO  io.pedestal.http.cors - {:msg "cors response processing", :cors-headers {"Access-Control-Allow-Origin" "", "Access-Control-Allow-Credentials" "true", "Access-Control-Expose-Headers" "Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-Xss-Protection, X-Download-Options, X-Permitted-Cross-Domain-Policies, Content-Security-Policy, Vaserequest-Id, Content-Type"}, :line 111}

Datomic: (checked with datomic console, schema is applied, only the transaction is created) 13194139534317 :db/txInstant #inst "2017-02-04T09:50:22.443-00:00" true

Environment

OS: Mac El Captain - 10.11.6 JVM: jdk1.8.0_74 Leiningen: 2.7.1 Clojure: 1.9.0-alpha14 Pedestal: 0.5.2 Vase: 0.9.0

Datomic Transactor: datomic-free-0.9.5544

(generated on 3. Feb. with lein new vase anytitle)

ohpauleez commented 7 years ago

All POST bodies have to be under the "payload" key. The purpose is to minimize key clashing where a body gets posted to various systems. It also allows you to transact multiple entities with a single POST. This may be changed in future versions of Vase, but it's generally useful to have uniform handling of single/multiple transactions across all POST endpoints.

Try the following cURL command: curl -H "Content-Type: application/json" -X POST -d '{"payload": [{"user/userId":"42","user/email":"user@example.com"}]}'

nottmey commented 7 years ago
curl -H "Content-Type: application/json" -X POST -d '{"payload": [{"user/userId":"42","user/email":"user@example.com"}]}' http://localhost:8080/api/accounts/v1/user

resulted in

e a v added
13194139534323 :db/txInstant #inst "2017-02-04T13:08:41.859-00:00" true
17592186045428 :user/userId 42 true
17592186045428 :user/email user@example.com true

with the response

{"whitelist":[{"user/userId":"42","user/email":"user@example.com"}],"transaction":[[null,null,null],[null,null,null],[null,null,null],[null,null,null]]}

So using the payload wrapper works. Thank you! (Also solves a question about bulk adding. Tested multiple entities and it worked. Wrapping and Bulk adding is missing in the tutorial right now.)

ohpauleez commented 7 years ago

Thanks for reaching out with the issue!

Form data isn't supported by the transact action literal at this time (it only pulls data out of JSON payloads). At one point, Vase transact did support form data, but we've mainly used Vase JSON-based microservices, where every client was talking JSON (and in some cases, Transit).

I'm going to leave this issue open to address two main things:

mtnygard commented 7 years ago

I will fix the docs.

ohpauleez commented 7 years ago

Master now has the transact fix -- you'll see EAV vectors of the successful transaction.

Thanks @mtnygard for doc updates!