Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base URL is not working #7

Closed
MortalFlesh opened this issue Nov 2, 2021 · 14 comments
Closed

Base URL is not working #7

MortalFlesh opened this issue Nov 2, 2021 · 14 comments

Comments

@MortalFlesh
Copy link

Hello,

if I add .BaseURL(...) the app won't match any of my resources.

I've tried this in multiple apps with the same result.

.AddJsonApi()
    .BaseUrl(baseUrlForJsonApiResources)
    .GetCtxAsyncRes(JsonApiContext.getCtx)
    // .BaseUrl(baseUrlForJsonApiResources)  // it is the same no matter if it is before or after the .GetCtxAsyncRes call
    .Add()

It worked fine on 16 version but now I've updated to 17.5 and it is broken. Without the .BaseUrl call, the app works just fine.

Thank you for any advice.

@cmeeren
Copy link
Owner

cmeeren commented Nov 2, 2021

I have passing tests that cover .BaseUrl, so I need more information. What is the value of baseUrlForJsonApiResources? Could you create a minimal repro solution and either publish it to GitHub, or zip it and upload here?

@MortalFlesh
Copy link
Author

Ok I will do such an example. It will take some time though.

@MortalFlesh
Copy link
Author

Well it was faster than I though. There is an example app here: https://github.com/MortalFlesh/json-api-example

In this shape, the app is working on my machine :)

macOS Big Sur 11.5
dotnet: 5.0.401
paket: Paket version 6.1.3+85755313dbc30c3c8916bb23d6e584ad9ef50ddd
fake: 5.20.4

The problem is on the Line 45 or Line 51

If baseURL is enabled, resource /services is not found.

It is simplified version of my real app, but it is fairly similar by the architecture point of view.

@MortalFlesh
Copy link
Author

MortalFlesh commented Nov 2, 2021

Btw with version 16.4 it worked - here is the example https://github.com/MortalFlesh/json-api-example/compare/with-version-16?expand=1

This is expected result for http://0.0.0.0:8090/services:

{
    "data": [
        {
            "type": "services",
            "id": "example-app1",
            "links": {
                "self": "https://example-router.host/Example-JsonApi/services/example-app1"
            }
        },
        {
            "type": "services",
            "id": "example-app2",
            "links": {
                "self": "https://example-router.host/Example-JsonApi/services/example-app2"
            }
        },
        {
            "type": "services",
            "id": "example-app3",
            "links": {
                "self": "https://example-router.host/Example-JsonApi/services/example-app3"
            }
        },
        {
            "type": "services",
            "id": "example-app4",
            "links": {
                "self": "https://example-router.host/Example-JsonApi/services/example-app4"
            }
        },
        {
            "type": "services",
            "id": "example-app5",
            "links": {
                "self": "https://example-router.host/Example-JsonApi/services/example-app5"
            }
        }
    ]
}

@cmeeren
Copy link
Owner

cmeeren commented Nov 2, 2021

Hi,

Can you try v0.17.7, which will be published shortly? I have fixed a problem with base URL there, though I'm not sure if it's what you're experiencing; in my instance, it manifested itself as a startup exception.

If it is not fixed:

I see there is still quite a bit of "noise" in your repro that is not relevant to JSON:API, and which could influence the result. Also, it's not clear to me from looking at the code what the actual base URL you are using, is. It seems to come (partially, at least) from some kind of framework I don't know about, and which shouldn't be in a minimal repro. So if it's not fixed, could you try modifying the Felicity.SampleApi in this repository to provoke the error?

@MortalFlesh
Copy link
Author

MortalFlesh commented Nov 3, 2021

I intentionally left a "noise" there (at minimum level), to show how I use the Felicity.

So I updated Felicity to 17.7 and I prepared a branch without a noise minimal-json-api and it still behaves the same.

I also tried to remove the router and other Saturn options - with no change.

let app = application {
    url "http://0.0.0.0:8090/"
    // use_router webApp
    // memory_cache
    // use_static "public"
    // use_gzip

    app_config configureApp
    service_config (configureServices baseUrlForJsonApiResources)
}

💡 Yet if the base URL is just a host without a path https://example-router.host it works.

{
    "data": [
        {
            "type": "services",
            "id": "example-app1",
            "links": {
                "self": "https://example-router.host/services/example-app1"
            }
        },
        {
            "type": "services",
            "id": "example-app2",
            "links": {
                "self": "https://example-router.host/services/example-app2"
            }
        },
        {
            "type": "services",
            "id": "example-app3",
            "links": {
                "self": "https://example-router.host/services/example-app3"
            }
        },
        {
            "type": "services",
            "id": "example-app4",
            "links": {
                "self": "https://example-router.host/services/example-app4"
            }
        },
        {
            "type": "services",
            "id": "example-app5",
            "links": {
                "self": "https://example-router.host/services/example-app5"
            }
        }
    ]
}

Unfortunately this is not enough for my case, since I need the base url to be host with path to work properly.

@cmeeren
Copy link
Owner

cmeeren commented Nov 3, 2021

I can't reproduce the problem using your repro. It seems to work fine. When using .BaseUrl, I call http://0.0.0.0:8090/example-json-api/services (note that I use the path from the configured URL), and that works. Is that not what you expect? If so, can you elaborate?

@MortalFlesh
Copy link
Author

Oh I see.. it finally makes sense.

Yet I need something quite different then accessing the application on the base url directly. What I need (and what worked before) is, that my application is running on http://0.0.0.0:8090/services but shows the value of resource links with the base url I set in the method baseUrl.

I mentioned it before, but I will try to write it more explicitly:

There should be following response on http://0.0.0.0:8090/services:

{
    "data": [
        {
            "type": "services",
            "id": "example-app1",
            "links": {
                "self": "https://example-router.host/example-json-api/services/example-app1"
            }
        },
        ...
    ]
}

On version 16.* it was done simply by running the application like this:

let app = application {
    url "http://0.0.0.0:8090/"  // set up the real host of the application
    ...
}
.AddJsonApi()
    .BaseUrl("https://example-router.host/example-json-api")  // set up the base url for links in resources
    ...

The reason for this is that my application is running as a service registered in consul and exposed by fabio router. Fabio router runs as a base url for all services in a certain domain (in this example the fabio router host is https://example-router.host/ so the domain in that case would be example). The service itself would be example-json-api. Router itself can route many services and each of them has its own path in the router. But the actual application is running inside a docker on 0.0.0.0.8090 and router forwards everything to the service.

This is just an explanation of how it works, I guess it is out of a scope of this problem though. What I'd like to have is the possibility of "fake" the base url in resource links, as it was possible before and still access the resource on the url I've set up in the application CE.

So in my case I don't really need the application to be able to answer the request on the base url I've set up in the JsonApi since the router will actually send just /service path to the http://0.0.0.0:8090/ docker app.

It's quite verbose and complicated but I hope it helped.

@cmeeren
Copy link
Owner

cmeeren commented Nov 3, 2021

Sure, I get what you need: Decouple the path in the URLs in the response from the path the API is actually available at.

The change should be simple, but it would be breaking. Though it would only be breaking since v0.17.0, so I guess it's not that critical.

I'll have a look at it tomorrow.

@MortalFlesh
Copy link
Author

Yes thats better way to put it.

Btw it may not be breaking if the new method serve that purpose - you can keep baseUrl as is and introduce new method - like resourceLinkBaseUrl.

@cmeeren
Copy link
Owner

cmeeren commented Nov 4, 2021

I already have BaseUrl and RelativeJsonApiRoot which together conceptually fully cover all use-cases (including yours). So I plan to make it possible to combine them. But I may be able to do it in a non-breaking manner.

@cmeeren cmeeren closed this as completed in 0437c50 Nov 4, 2021
@cmeeren
Copy link
Owner

cmeeren commented Nov 4, 2021

Version 0.17.8 will be published soon and supports your use-case. For details, see the documentation sections on RelativeJsonApiRoot and BaseUrl.

@MortalFlesh
Copy link
Author

Thank you for a quick solution a understanding :)

I just want to confirm, that this works as expected.

.BaseUrl(Uri ("https://example-router.host/example-json-api"))
.RelativeJsonApiRoot("/")

@cmeeren
Copy link
Owner

cmeeren commented Nov 4, 2021

Happy to hear it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants