Fork me on GitHub
#juxt
<
2021-09-22
>
chromalchemy16:09:16

@oliy I am having some trouble getting https://github.com/oliyh/martian bootstrapped with my API. My https://developer.bigcommerce.com/api-docs/getting-started/authentication/rest-api-authentication#obtaining-store-api-credentials#obtaining-store-api-credentials is https://raw.githubusercontent.com/bigcommerce/api-specs/master/reference/catalog.v3.yml is located on a repo; not on an api route. The file is .yml (but I am assuming it is fine to convert to .json). Also I need to pass an authentication token in the header. I'm not sure how to pass the spec file in, seperatly for the api path/request config. Would i be impacted by the caveat: > You need `:operationId` in the OpenAPI/Swagger spec to name routes when using `bootstrap-openapi` Here is my current code (not sure where to attempt to add swagger api-spec file/data?)

(def add-authentication-header
  {:name ::add-authentication-header
   :enter (fn [ctx]
            (assoc-in ctx [:request :headers "Authorization"] (str "Token: " mytoken)))})

(let
  [url catalog-api-url
   base-url api-base-url 
   opts {:interceptors 
         (concat martian-http/default-interceptors
           [add-authentication-header])}
            ;martian-http/encode-body
            ;(martian-http/coerce-response)
            ;martian-http/perform-request])}
   definition (:body (http/get url {:as :json}))
   {:keys [scheme server-name server-port]} 
   {:scheme :https,
    :server-name "",
    :server-port nil,}
   m (martian/bootstrap-openapi base-url definition opts)]
  (martian/explore m))

oliy16:09:58

that yml file seems to have operationId, so you should be ok. you will need to convert to json to use bootstrap-openapi

oliy16:09:44

that authentication header interceptor should work fine, you just need to insert it into your interceptor stack

chromalchemy16:09:14

How do you pass a .json file, or string?

chromalchemy16:09:26

I am currently concat add-authentication-header to default-interceptors per this example (I don't need the other items in that example?)

chromalchemy17:09:25

@oliy I see that definition should be the api spec. (slurp myswagger.json) is ok for this? I simplified the bootstrap code: Now I am getting an empty vecor (instead of request error code) (seems like it cannot find any routes?)

(let
  [base-url
     ""
     ;""
     ;""
   opts {:interceptors
         (concat martian-http/default-interceptors
           [{:name ::add-authentication-header
             :enter
             (fn [ctx]
               (assoc-in ctx [:request :headers "Authorization"] (str "X-Auth-Token: " mytoken)))}])}
   definition (slurp "myswagger.json")
   scheme :https
   server-name ""
   server-port nil
   m (martian/bootstrap-openapi base-url definition opts)]
  (martian/explore m))
A normal GET request looks like this:
GET 
X-Auth-Token: {{ACCESS_TOKEN}}
Content-Type: application/json
Accept: application/json
Does the interceptor modification look ok? What is up with "Authorization" string there?
(assoc-in ctx [:request :headers "Authorization"] (str "X-Auth-Token: " mytoken))
Are the scheme, server-name, and server-port vars even being used here?

chromalchemy17:09:43

Should "basePath": "/stores/{$$.env.store_hash}/v3" continue to have this route variable in the api-spec json document? Or should I hardcode my store hash value like "basePath": "/stores/7hstasnrjg/v3" Given the above basePath , what should the api base-url var be?

oliy18:09:17

Server-name, basePath support etc isn't great, I think it tries to concat basePath on to the bootstrap URL to make the relative paths in the definition into absolute ones

chromalchemy18:09:24

So should api-root in bootstrap-openapi fn be like: full explicit url like

or basePath like /stores/7hstasnrjg/v3 or basePath + route like /stores/7hstasnrjg/v3/catalog/summary https://developer.bigcommerce.com/api-reference/store-management/catalog from docs:
Host: 
Protocols: https
Accepts: application/json
Responds With: application/json
ex: GET /stores/7hstasnrjg/v3/catalog/summary Also, when generating a request from docs, token key was written like
.header("content-type", "application/json")
.header("accept", "application/json")
.header("x-auth-token", token)
Before I had different casing..

chromalchemy18:09:56

@oliy I got it working! I think 3 things were off in my earlier attempts: Authentification token header needed to be formated like this

(fn [ctx]
  (assoc-in ctx [:request :headers "x-auth-token"] mytoken))
base-url was not the entire url, but the basePath fragment
base-url "/stores/7hstasnrjg/v3"
And I needed to read the escaped file string with a JSON reader
(def swagger-json
  (cheshire/parse-string
    (slurp "myswagger.json")))
Working version:
(let
  [base-url "/stores/7hstasnrjg/v3"
   opts {:interceptors
         (concat martian-http/default-interceptors
           [{:name ::add-authentication-header
             :enter
             (fn [ctx]
               (assoc-in ctx [:request :headers "x-auth-token"] mytoken))}])}
   definition swagger-json
   {:keys [scheme server-name server-port]}
   {:scheme :https
    :server-name ""
    :server-port nil}
   m (martian/bootstrap-openapi base-url definition opts)]
  (martian/explore m))

chromalchemy19:09:10

@oliy When I try to build a url or request, the server base is not in url

(martian/url-for m :get-category-by-id {:category-id 654})
=> "/stores/7hstasnrjg/v3/catalog/categories/654"
It seems like this config in the bootstrap code
(let [{:keys [scheme server-name server-port]}
      {:scheme :https
       :server-name ""
       :server-port nil}
Is not being called by anything... Can you advise how this should be configured?

oliy19:09:36

Your base-url needs to be an absolute one that points to the API root

chromalchemy20:09:38

Ok thanks, it is working now with this

base-url ""

oliy21:09:59

Yep looks good