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

Different domains for different functions #165

Open
zirkelc opened this issue Oct 1, 2018 · 12 comments
Open

Different domains for different functions #165

zirkelc opened this issue Oct 1, 2018 · 12 comments

Comments

@zirkelc
Copy link

zirkelc commented Oct 1, 2018

Is it possible to have different domains pointing to different functions within the same service?

For example:
abc.com points to function handle-abc, and xyz.com points to function handle-xyz. Both functions are defined within the same serverless.yaml.

@jconstance-amplify
Copy link
Collaborator

Hi @chriszirkel,

Not in the way that this plugin is currently structured. The easiest solution would probably be to split the functions into different serverless.yaml files.

@zirkelc
Copy link
Author

zirkelc commented Oct 2, 2018

Yes, that's what I was thinking of. The problem is these services share the same resources and variables, so I have to duplicate those in two serverless.yaml files. Furtheremore, I am using the csharp template and having just one service and project gives me the possibility to share a lot of code between those two functions.

@jconstance-amplify
Copy link
Collaborator

You could try splitting common things out into another file and read that into both of your serverless.yaml files https://serverless.com/framework/docs/providers/aws/guide/variables#reference-variables-in-other-files

@zirkelc
Copy link
Author

zirkelc commented Oct 3, 2018

Yes, that's what I am doing now. I got two services that I would like to assign two different domains. Because they use the same other resources (database tables), I split them up in a third service for get, create, update and delete an item from the database. Unfortunately, I have to hard-code the names of the third service functions in my two previous services. Is there a possibility two export those service function names (get-item, create-item, ...) and access threir names them via some env variables?

BTW: Are you planning to support multiple domains in one serverless.yaml any time in the future?

@jconstance-amplify
Copy link
Collaborator

jconstance-amplify commented Oct 3, 2018

Yes, serverless natively supports that: https://serverless.com/framework/docs/providers/aws/guide/variables#referencing-environment-variables

I wouldn't be opposed to someone sending a PR for that, but I wouldn't consider it a priority for me or anyone else at Amplify to do. Do you have a proposal for how you think that should be structured? I suspect you'd have some issues with it because of how Serverless handles API Gateway creation right now, but would be interested to see how folks would like to see the problem be solved.

@zirkelc
Copy link
Author

zirkelc commented Oct 3, 2018

I could think of two options how to structure it:

  • addtional customDomains attribute with a list of functions:
custom:
  customDomains:
    first_domain:
      domainName: abc.com
      functions:
        - get-abc
        - create-abc
      basePath: ''
      stage: ${self:provider.stage}
      createRoute53Record: true
    second_domain:
      domainName: xyz.com
      functions:
        - get-xyz
        - create-xyz
      basePath: ''
      stage: ${self:provider.stage}
      createRoute53Record: true 
  • assign customDomain per function, and overide the default customDomain
functions:
  get-abc:
    handler: handler.abc_handler
    events: 
      - http:
        path: /
        method: get
    # override default customDomain      
    customDomain:
      domainName: abc.com
      basePath: ''
      stage: ${self:provider.stage}
      createRoute53Record: true

custom:
  # default custom domain for all functions
  customDomain:
    domainName: xyz.com
    basePath: ''
    stage: ${self:provider.stage}
    createRoute53Record: true    

@Throttlebyte
Copy link

Throttlebyte commented Oct 3, 2018

We have a need for similar functionality: to configure multiple custom domains within the same service. Our use-case doesn't need to bind to functions directly, but to assign multiple subdomains to different base paths within a single service.

What I had in mind was just to optionally pass an array of objects (containing the current config schema) to the existing key and add a check to see if customDomain is an object or array of objects. If it is an array it would iterate them and apply the same logic it does now.

# Current configuration is maintained
custom:
  customDomain:
    domainName: api.foo.com
    stage: ci
    basePath: api
    certificateName: '*.foo.com'
    createRoute53Record: true
    endpointType: 'regional'

# Optional configuration with multiple domains
custom:
  customDomain:
  - domainName: abc.foo.com
    stage: ci
    basePath: abc
    certificateName: '*.foo.com'
    createRoute53Record: true
    endpointType: 'regional'

  - domainName: xyz.foo.com
    stage: ci
    basePath: xyz
    certificateName: '*.foo.com'
    createRoute53Record: true
    endpointType: 'regional'

@chriszirkel would this work for your use-case? To do the above and configure your functions this way:

functions:
  get-abc:
    handler: handler.abc_handler
    events: 
      - http:
        path: /abc
        method: get
  get-xyz:
    handler: handler.xyz_handler
    events: 
      - http:
        path: /xyz
        method: get

@zirkelc
Copy link
Author

zirkelc commented Oct 4, 2018

Yes, to apply different basePaths could work for me, as long as those basePaths are hidden via the created custom domain in API gateway. So that I can call the custom domain and it will map to the aws domain with stage and basePath:

  • abc.foo.com/ -> 12345.us-east-1.execute-api.amazonaws.com/dev/abc/
  • xyz.foo.com/ ->12345.us-east-1.execute-api.amazonaws.com/dev/xyz/

@jconstance-amplify
Copy link
Collaborator

I'm not sure AWS actually supports this particular use case @chriszirkel. As far as I know, you can only point a Custom Domain at a given API Gateway, not particular functions inside that API Gateway. So I don't think you could achieve what you want whilst operating inside those limitations. Are you able to make that setup happen in the AWS Console today? Maybe I'm missing something. I think you might be able to set it up via a Cloudfront Distribution...

@Throttlebyte So just to be clear, you want xyz.foo.com/xyz and abc.foo.com/abc to point to the same API Gateway?

@Throttlebyte
Copy link

@jconstance-amplify We won't need to use any path mapping, but yes- we'd like xyz.foo.com and abc.foo.com to point to the same API Gateway.

@chriszirkel I mistook which side the mapping applied to (I was thinking it mapped and effectively removed pieces of the API path, but it adds to the custom domain path to stitch in multiple services)- you may be able to hide the first part of your path the way you'd like by using stage variables: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-set-stage-variables-aws-console.html

@zirkelc
Copy link
Author

zirkelc commented Oct 7, 2018

I'm not sure AWS actually supports this particular use case @chriszirkel. As far as I know, you can only point a Custom Domain at a given API Gateway, not particular functions inside that API Gateway. So I don't think you could achieve what you want whilst operating inside those limitations. Are you able to make that setup happen in the AWS Console today? Maybe I'm missing something. I think you might be able to set it up via a Cloudfront Distribution...

@Throttlebyte So just to be clear, you want xyz.foo.com/xyz and abc.foo.com/abc to point to the same API Gateway?

Yes, you're right, it seems not to be possible to point a custom domain to a function/method. The only way would be to deploy multiple API Gateways for multiple functions.

If you define multiple API Gateways as cloudformation resources within serverless.yaml, then it should easily be possible to create multiple custom domains, right? On the other hand, to manually define all those API mappings as resources seems like a big overhead to achieve that...

@sridhar562345
Copy link

sridhar562345 commented Nov 30, 2021

I think It will be better, if there is a option to reference a domain to a function as below.

custom:
  customDomain:
    domain1:
      domainName:  abc.foo.com
      stage: ci
      basePath: abc
      certificateName: '*.foo.com'
      createRoute53Record: true
      endpointType: 'regional'
   domain2:
      domainName: xyz.foo.com
      stage: ci
      basePath: xyz
      certificateName: '*.foo.com'
      createRoute53Record: true
      endpointType: 'regional'

And we should be able to reference the domain like below

functions:
  get-abc:
    handler: handler.abc_handler
    events: 
      - http:
        path: /abc
        method: get
    domain: ref{customDomain.domain1}

  get-xyz:
    handler: handler.xyz_handler
    events: 
      - http:
        path: /xyz
        method: get
    domain: ref{customDomain.domain2}

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

No branches or pull requests

6 participants