# Open-generator-cli problems, or Swagger/OpenApi recommendations

**URL:** <https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644>\
**Category:** Request Feedback\
**Created:** [November 9, 2019, 11:20am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644 "2019-11-09T11:20:23Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 23, 2019, 1:29pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/41 "2019-12-23T13:29:55Z")

</div>

I think it is the following code in your Api.send that adds the extra initial /

`Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams`

See the samples in

[https://package.elm-lang.org/packages/elm/url/latest/Url-Builder#crossOrigin](https://package.elm-lang.org/packages/elm/url/latest/Url-Builder#crossOrigin)

Cross origin ads / on its own, I think you shouldn’t use it, since there are already the correct number of slashes in swagger.json.

```
crossOrigin prePath pathSegments parameters =
  prePath ++ "/" ++ String.join "/" pathSegments ++ toQuery parameters

```

instead we should use our own definition:

```
joinPath prePath pathSegments parameters =
  prePath ++ String.join "/" pathSegments ++ toQuery parameters

```

Most likely, you have double slashes in your samples too, but your webserver is less picky, since some will just ignore duplicate /

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [December 23, 2019, 2:14pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/42 "2019-12-23T14:14:59Z")

</div>

> [@mattiasw](#):
>
> Look at the screenshot above, that is how I found that Elm expected a string, and got an int. I expected it would have been by an Err-msg, i.e. that my client would have presented it as any Http-ajax-error message, for example a network timeout.

That’s strange indeed. I would expect an Elm `Err` as well. I’ll see if I get to reproduce this one.

> [@mattiasw](#):
>
> In the swagger.json file, there is no /

Ah yes, I think it is in splitting the path string.

Here’s a [new release](https://drive.google.com/open?id=1Ae2b4trjOmzRGfZZN4iiDgo2KzLbmiQY) including:

- Improved handling of reserved and unsafe words;
- Improved `Api` functions (including the argument swap);
- Support for numeric enums;
- A fix for removing the additional slash in paths.

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 23, 2019, 7:49pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/43 "2019-12-23T19:49:30Z")

</div>

Not perfect yet. Only works for simple path like

```
    "/Version"

```

but not for ones like

```
    "/Cmd/{cmdName}"

```

I am not sure why we work with splitted paths, we should just concatenate and replace.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [December 23, 2019, 8:11pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/44 "2019-12-23T20:11:02Z")

</div>

What doesn’t work in the latter case? For me it is working fine.

The reason I use the split here is that I would like to stick with the native `Url.Builder`. That comes with type-checking and is already tested code.

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 24, 2019, 8:53am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/45 "2019-12-24T08:53:35Z")

</div>

The 2nd / between in /Cmd/{cmdName} is removed during the process. The Url.Builder code for the path part is really simple, no need to reuse that one.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [December 24, 2019, 9:37am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/46 "2019-12-24T09:37:28Z")

</div>

It is not removed for me. Both for empty and non-empty `cmdName`s it is working fine. Are you using v7? Are you running in reactor or do you build and minify?

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 25, 2019, 9:35am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/47 "2019-12-25T09:35:43Z")

</div>

Found the problem, it was my code that misused yours, and due to the splitting, there were problems. I am now using an Api.elm without the splitting, but I will adapt the rest of the code to the splitting.

```
 sss6elm/src/Api.elm | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/sss6elm/src/Api.elm b/sss6elm/src/Api.elm
index 50788c4..2337230 100644
--- a/sss6elm/src/Api.elm
+++ b/sss6elm/src/Api.elm
@@ -21,7 +21,7 @@ type Request a
         { method : String
         , headers : List Http.Header
         , basePath : String
- , pathParam : String
+ , pathParams : List String
         , queryParams : List Url.Builder.QueryParameter
         , body : Http.Body
         , decoder : Json.Decode.Decoder a
@@ -36,7 +36,7 @@ request method path pathParams queryParams headerParams body decoder =
         { method = method
         , headers = headers headerParams
         , basePath = "http://localhost:5000"
- , pathParam = interpolatePath path pathParams
+ , pathParams = interpolatePath path pathParams
         , queryParams = queries queryParams
         , body = Maybe.withDefault Http.emptyBody (Maybe.map Http.jsonBody body)
         , decoder = decoder
@@ -50,7 +50,7 @@ send toMsg (Request req) =
     Http.request
         { method = req.method
         , headers = req.headers
- , url = joinUrl req.basePath req.pathParam req.queryParams
+ , url = Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams
         , body = req.body
         , expect = Http.expectJson toMsg req.decoder
         , timeout = req.timeout
@@ -64,7 +64,7 @@ map fn (Request req) =
         { method = req.method
         , headers = req.headers
         , basePath = req.basePath
- , pathParam = req.pathParam
+ , pathParams = req.pathParams
         , queryParams = req.queryParams
         , body = req.body
         , decoder = Json.Decode.map fn req.decoder
@@ -107,19 +107,17 @@ headers =
     List.filterMap (\( key, value ) -> Maybe.map (Http.header key) value)
 
 
-interpolatePath : String -> List ( String, String ) -> String
+interpolatePath : String -> List ( String, String ) -> List String
 interpolatePath rawPath pathParams =
     let
         interpolate =
             \( name, value ) path -> String.replace ("{" ++ name ++ "}") value path
     in
     List.foldl interpolate rawPath pathParams
+ |> String.split "/"
+ |> List.drop 1
 
 
 queries : List ( String, Maybe String ) -> List Url.Builder.QueryParameter
 queries =
     List.filterMap (\( key, value ) -> Maybe.map (Url.Builder.string key) value)
-
-
-joinUrl prePath pathParam parameters =
- prePath ++ pathParam ++ Url.Builder.toQuery parameters
```

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 26, 2019, 10:31am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/48 "2019-12-26T10:31:01Z")

</div>

Everything works fine with your generated code now. Thanks!

A minor that is more Elm-related, related on how elm finds stuff which I still do not fully understand :-). Sometimes dot means inside module sometimes dot is path related. I am trying to define my own wrapper Api.send, so that I can overwrite the configuration like using absolute urls etc. I thought replacing Request by Api.Request would be enough, and that is true for the typing, but not for destructing the request object.

I copied the definition into my own file, just redirect works fine:

```
send : (Result Http.Error a -> msg) -> Api.Request a -> Cmd msg
send =
    Api.send

```

but when I try to decompose the Request object, it fails to compile. What is missing?

```
send : (Result Http.Error a -> msg) -> Api.Request a -> Cmd msg
send toMsg (Api.Request req) =
    Http.request
        { method = req.method
        , headers = req.headers
        , url = Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams
        , body = req.body
        , expect = Http.expectJson toMsg req.decoder
        , timeout = req.timeout
        , tracker = req.tracker
        }

```

I get

```
I cannot find a `Api.Request` variant:

59| send toMsg (Api.Request req) =
                ^^^^^^^^^^^
The `Api` module does not expose a `Request` variant. These names seem close
```

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [December 26, 2019, 12:20pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/49 "2019-12-26T12:20:36Z")

</div>

Great things are working well now!

> [@mattiasw](#):
>
> I am trying to define my own wrapper Api.send, so that I can overwrite the configuration like using absolute urls etc. I thought replacing Request by Api.Request would be enough, and that is true for the typing, but not for destructing the request object.

The idea should be that you do not have to overwrite anything. The `Request` type allows for modifications, like changing the base path or adding headers (see `Api.elm`). Is there anything you wish to do there which is currently not possible?

The reason you are getting that error is because `Request` is a so-called _opaque_ type. This means the type itself is exposed but the type constructor is not (which would be the case if the module exposed `Request(..)`). This means you cannot (1) directly instantiate a `Request` from outside the module and (2) you cannot do pattern matching on the type. The nice thing about this is that is allows for creating types without exposing the implementation details to the outer world. It forces users to only use the type as was inentend to be used.

Edit: The goal is to have your own `send` look something similar to this:

```elm
send : Server -> (Result Http.Error a -> msg) -> Request a -> Cmd msg
send { basePath, accessToken } toMsg request =
    request
        |> Api.withBasePath basePath
        |> Api.withHeader "ACCESS_TOKEN" accessToken
        |> Api.send toMsg

-- where
type alias Server =
    { basePath : String
    , accessToken : String
    }

```

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 26, 2019, 1:12pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/50 "2019-12-26T13:12:32Z")

</div>

Thanks! Good sample for your docs.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [December 26, 2019, 1:45pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/51 "2019-12-26T13:45:58Z")

</div>

> [@mattiasw](#):
>
> Good sample for your docs.

Thanks, I copied it from there 😄

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 26, 2019, 4:23pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/52 "2019-12-26T16:23:15Z")

</div>

What are the link to the docs? that is one thing I never found for the elm openapi generator.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [December 30, 2019, 1:23pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/53 "2019-12-30T13:23:37Z")

</div>

> [@mattiasw](#):
>
> What are the link to the docs? that is one thing I never found for the elm openapi generator.

That’s because it never existed.  
I never had (made) the time to write some docs.

I just finished my first attempt (so it might still be a little rough), please have a look here: [Introduction · Elm with OpenAPI](https://eriktim.github.io/openapi-elm/).

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [December 31, 2019, 12:29pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/54 "2019-12-31T12:29:53Z")

</div>

Thank you @eriktimmers

I understood everything directly, except the Api.map part, maybe you should extend that so that is obvious when to use it, in combination with Api.send, or when you build the Request.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [January 3, 2020, 10:18am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/55 "2020-01-03T10:18:24Z")

</div>

Thanks, @mattiasw.

I’ll expand the example on `Api.map` a bit.  
Are there any things missing in the guide that you think should be added?

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [January 3, 2020, 11:34am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/56 "2020-01-03T11:34:42Z")

</div>

I will have a 2nd reading through, but I think the next step is to have a small complete sample, like the petstore. However, I understand that that is a non-trivial task.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [January 3, 2020, 12:17pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/57 "2020-01-03T12:17:29Z")

</div>

That’s what I tried to do with the Star Wars example. What do you think about that one?

---

<div class="post-metadata">

**Author:** ![mattiasw](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattiasw/32/908_2.png) [@mattiasw](https://discourse.elm-lang.org/u/mattiasw)\
**Post date:** [January 3, 2020, 12:37pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/58 "2020-01-03T12:37:12Z")

</div>

Sorry, missed that. Are we talking about

> **[eriktim/openapi-elm](https://github.com/eriktim/openapi-elm/tree/master/example)**
>
> Guide on using the OpenAPI Generator for Elm. Contribute to eriktim/openapi-elm development by creating an account on GitHub.

I prefer to have a complete sample, so that I can look at all code.

Also, is it possible to publish a working version of it?

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [January 9, 2020, 8:29am UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/59 "2020-01-09T08:29:01Z")

</div>

> [@mattiasw](#):
>
> Sorry, missed that. Are we talking about

Yes we are.

> [@mattiasw](#):
>
> I prefer to have a complete sample, so that I can look at all code.

You mean you wouldn’t have to generate the code? I’d rather not add it to the repo as I think it good to make clear this code needs to be generated.

> [@mattiasw](#):
>
> Also, is it possible to publish a working version of it?

I can try to publish it as well. That actually makes sense.

---

<div class="post-metadata">

**Author:** ![eriktimmers](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/eriktimmers/32/1114_2.png) [@eriktimmers](https://discourse.elm-lang.org/u/eriktimmers)\
**Post date:** [January 12, 2020, 12:24pm UTC](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644/60 "2020-01-12T12:24:13Z")

</div>

> [@mattiasw](#):
>
> Also, is it possible to publish a working version of it?

It now gets published from travis on [Main](https://eriktim.github.io/openapi-elm/example/)

[Previous page](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644.md?page=2)

[Next page](https://discourse.elm-lang.org/t/open-generator-cli-problems-or-swagger-openapi-recommendations/4644.md?page=4)
