I already have the ElasticBeanstalk (Multicontainer) template. In addition to that, I want to get Docker image from ECR which I already have ****.dkr.ecr.ap-south-1.amazonaws.com/traveltouch:latest in my ECR repo. (If want to create new repo also fine). I mentioned that image in my Dockerrun.json and Dynamodb also needed. Here how to attach that permission and add My ECR repo and new dynamodb table into to my MyInstanceProfile and the cloudformation.
AWSTemplateFormatVersion: '2010-09-09'
Resources:
sampleApplication:
Type: AWS::ElasticBeanstalk::Application
Properties:
Description: AWS Elastic Beanstalk Sample Application
sampleApplicationVersion:
Type: AWS::ElasticBeanstalk::ApplicationVersion
Properties:
ApplicationName:
Ref: sampleApplication
Description: AWS ElasticBeanstalk Sample Application Version
SourceBundle:
S3Bucket: !Sub "elasticbeanstalk-ap-south-1-182107200133"
S3Key: TravelTouch/Dockerrun.aws.json
sampleConfigurationTemplate:
Type: AWS::ElasticBeanstalk::ConfigurationTemplate
Properties:
ApplicationName:
Ref: sampleApplication
Description: AWS ElasticBeanstalk Sample Configuration Template
OptionSettings:
- Namespace: aws:autoscaling:asg
OptionName: MinSize
Value: '2'
- Namespace: aws:autoscaling:asg
OptionName: MaxSize
Value: '6'
- Namespace: aws:elasticbeanstalk:environment
OptionName: EnvironmentType
Value: LoadBalanced
- Namespace: aws:autoscaling:launchconfiguration
OptionName: IamInstanceProfile
Value: !Ref MyInstanceProfile
SolutionStackName: 64bit Amazon Linux 2018.03 v2.26.0 running Multi-container Docker 19.03.13-ce (Generic)
sampleEnvironment:
Type: AWS::ElasticBeanstalk::Environment
Properties:
ApplicationName:
Ref: sampleApplication
Description: AWS ElasticBeanstalk Sample Environment
TemplateName:
Ref: sampleConfigurationTemplate
VersionLabel:
Ref: sampleApplicationVersion
MyInstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Description: Beanstalk EC2 role
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier
- arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker
- arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier
MyInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref MyInstanceRole
and my Dockerrun.json
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [{
"environment": [{
"name": "POSTGRES_USER",
"value": "admin"
},
{
"name": "POSTGRES_PASSWORD",
"value": "postgres"
},
{
"name": "POSTGRES_DB",
"value": "traveldb"
}
],
"essential": true,
"image": "postgres:12-alpine",
"memory": 300,
"mountPoints": [{
"containerPath": "/var/lib/postgresql/data/",
"sourceVolume": "postgres_data"
}],
"name": "db",
"portMappings": [{
"containerPort": 5432,
"hostPort": 5432
}]
},
{
"essential": true,
"links": [
"db"
],
"name": "web",
"image": "****.dkr.ecr.ap-south-1.amazonaws.com/traveltouch:latest",
"memory": 300,
"portMappings": [{
"containerPort": 80,
"hostPort": 80
}]
}
],
"volumes": [{
"host": {
"sourcePath": "postgres_data"
},
"name": "postgres_data"
}
]
}
Related
I'm trying to get the list of all instance and its IP, I can able to fetch the instance name as info.resources.0.name, info.resources.1.name, info.resources.2.name etc. Similarly to fetch the network IP I tried info.resources.0.networkInterfaces.networkIP but that didn't work. I need help to rephrase the playbook to use with_items or loop to fetch the list of instances and it's IP. Below is the playbook task:
- name: get info on an instance
gcp_compute_instance_info:
zone: "{{ zone }}"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}"
register: info
- debug:
msg: "name - {{ info.resources.0.name }}"
Below is the detailed json output of single instance info:
PLAY [Create an instance] ******************************************************
TASK [get info on an instance] *************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": {
"changed": false,
"failed": false,
"resources": [
{
"canIpForward": false,
"confidentialInstanceConfig": {
"enableConfidentialCompute": false
},
"cpuPlatform": "AMD Rome",
"creationTimestamp": "2022-05-04T23:36:13.606-07:00",
"deletionProtection": false,
"description": "",
"disks": [
{
"autoDelete": true,
"boot": true,
"deviceName": "ansible-automation-platform",
"diskSizeGb": "50",
"guestOsFeatures": [
{
"type": "UEFI_COMPATIBLE"
},
{
"type": "VIRTIO_SCSI_MULTIQUEUE"
},
{
"type": "SEV_CAPABLE"
},
{
"type": "GVNIC"
}
],
"index": 0,
"interface": "SCSI",
"kind": "compute#attachedDisk",
"licenses": [
"https://www.googleapis.com/compute/v1/projects/rhel-cloud/global/licenses/rhel-8-server"
],
"mode": "READ_WRITE",
"source": "https://www.googleapis.com/compute/v1/projects/company_project_prod/zones/us-central1-a/disks/ansible-automation-platform",
"type": "PERSISTENT"
}
],
"displayDevice": {
"enableDisplay": false
},
"fingerprint": "tRhWl0y3JhA=",
"id": "3629531832562667187",
"kind": "compute#instance",
"labelFingerprint": "42WmSpB8rSM=",
"lastStartTimestamp": "2022-05-05T22:09:57.920-07:00",
"lastStopTimestamp": "2022-05-05T07:27:28.617-07:00",
"machineType": "https://www.googleapis.com/compute/v1/projects/company_project_prod/zones/us-central1-a/machineTypes/e2-custom-4-8192",
"metadata": {
"fingerprint": "3tGBZbor1YQ=",
"items": [
{
"key": "ssh-keys",
"value": "user_name:ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEYc1v1Vqgy1tiS1TIDtgNqd1M0Ycp/10q5WBYH8f1E9iXfdZYj6sRSVAzh4C4D0LD925m+mH6MPyr5393vJNcA= google-ssh {\"userName\":\"pugazhendhi.ramakrishnan#wipro.com\",\"expireOn\":\"2022-05-09T06:13:35+0000\"}\nuser_name:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHsNAKOXJCdLjgiYZrlYIQ0NS+dQcBIyxlJXNirKi4zpS4cOTM42FEFyEfByT5s6oexnh/LWLmB8qKGF7hTI7Xup44Nh0W20m2VMHwhGalDELa+KNtrVEg429KutUOC7VHNoSbthj/sVyJ7YiZuRLEPmWlh2VZPLqIvdVgIZ5DhOcAVpeoPEDEVwAMUgceci1d7iyqyVsFA6CcyFTcXqouUgXpjzm6a+6YL4wpSFcZntoVxCA8TFb35ZzXdsSoh1U86GGWRqsntpXHaI5H90z+DpwDg/G8BWSjtZ5vBBgk48n08yg3kLSG5B3mJKtilJhCdmSWqRAqOxpRUvA6kkpf google-ssh {\"userName\":\"pugazhendhi.ramakrishnan#wipro.com\",\"expireOn\":\"2022-05-09T06:13:51+0000\"}"
}
],
"kind": "compute#metadata"
},
"name": "ansible-automation-platform",
"networkInterfaces": [
{
"fingerprint": "WE1S5NA9wnc=",
"kind": "compute#networkInterface",
"name": "nic0",
"network": "https://www.googleapis.com/compute/v1/projects/company_project_prod/global/networks/default",
"networkIP": "10.128.0.17",
"stackType": "IPV4_ONLY",
"subnetwork": "https://www.googleapis.com/compute/v1/projects/company_project_prod/regions/us-central1/subnetworks/default"
}
],
"reservationAffinity": {
"consumeReservationType": "ANY_RESERVATION"
},
"scheduling": {
"automaticRestart": true,
"onHostMaintenance": "MIGRATE",
"preemptible": false,
"provisioningModel": "STANDARD"
},
"selfLink": "https://www.googleapis.com/compute/v1/projects/company_project_prod/zones/us-central1-a/instances/ansible-automation-platform",
"serviceAccounts": [
{
"email": "151315322722-compute#developer.gserviceaccount.com",
"scopes": [
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/servicecontrol",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/trace.append"
]
}
],
"shieldedInstanceConfig": {
"enableIntegrityMonitoring": true,
"enableSecureBoot": false,
"enableVtpm": true
},
"shieldedInstanceIntegrityPolicy": {
"updateAutoLearnPolicy": true
},
"startRestricted": false,
"status": "RUNNING",
"tags": {
"fingerprint": "42WmSpB8rSM="
},
"zone": "https://www.googleapis.com/compute/v1/projects/company_project_prod/zones/us-central1-a"
},
]
}
}
Given the simplified data
info:
changed: false
failed: false
resources:
- canIpForward: false
name: ansible-automation-platform
networkInterfaces:
- name: nic0
networkIP: 10.128.0.17
stackType: IPV4_ONLY
- name: nic1
networkIP: 10.128.0.18
stackType: IPV4_ONLY
- name: nic2
networkIP: 10.128.0.19
stackType: IPV4_ONLY
Iterate the selected names of the resources and combine a dictionary, e.g.
- set_fact:
name_ip: "{{ name_ip|d({})|
combine({item: dict(info.resources|json_query(_query))}) }}"
loop:
- ansible-automation-platform
vars:
_query: "[?name == '{{ item }}'].networkInterfaces[].[name,networkIP]"
gives
name_ip:
ansible-automation-platform:
nic0: 10.128.0.17
nic1: 10.128.0.18
nic2: 10.128.0.19
I'm trying to change the output format of the Gremlin http server to a Non typed JSON object like the one below.
{
"requestId": "320599c8-7d49-4cc6-87a6-42115009f90c",
"status": {
"message": "",
"code": 200,
"attributes": {}
},
"result": {
"data": [
{
"info": [
{
"total_seen": [
2845
],
"first_seen": [
1501568446000
],
"last_seen": [
1580157081000
],
"value": [
"http://test.com"
]
}
]
}
],
"meta": {}
}
}
But the response i get from the server is a typed one
{
"requestId": "e8621470-7ee7-4f6b-a8ea-1d49c85093c8",
"status": {
"message": "",
"code": 200,
"attributes": {
"#type": "g:Map",
"#value": []
}
},
"result": {
"data": {
"#type": "g:List",
"#value": [
{
"#type": "g:Map",
"#value": [
"info",
{
"#type": "g:List",
"#value": [
{
"#type": "g:Map",
"#value": [
"total_seen",
{
"#type": "g:List",
"#value": [
{
"#type": "g:Int32",
"#value": 2797
}
]
},
"first_seen",
{
"#type": "g:List",
"#value": [
{
"#type": "g:Int64",
"#value": 1501568446000
}
]
},
"last_seen",
{
"#type": "g:List",
"#value": [
{
"#type": "g:Int64",
"#value": 1578774368000
}
]
},
"vertex_type",
{
"#type": "g:List",
"#value": [
"url"
]
},
"url_value",
{
"#type": "g:List",
"#value": [
"http://test.com"
]
}
]
}
]
}
]
}
]
},
"meta": {
"#type": "g:Map",
"#value": []
}
}
}
I tried changing the settings in gremlin-server.yaml by commenting GraphSON V2 and V3
# Copyright 2019 JanusGraph Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
host: 127.0.0.1
port: 8182
scriptEvaluationTimeout: 30000
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
graphs: {
graph: conf/gremlin-server/janusgraph-cassandra-es-server.properties
}
scriptEngines: {
gremlin-groovy: {
plugins: { org.janusgraph.graphdb.tinkerpop.plugin.JanusGraphGremlinPlugin: {},
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]},
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/empty-sample.groovy]}}}}
serializers:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }}
# - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
# Older serialization versions for backwards compatibility:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: {ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
# - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
processors:
- { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
- { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}
metrics: {
consoleReporter: {enabled: true, interval: 180000},
csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
jmxReporter: {enabled: true},
slf4jReporter: {enabled: true, interval: 180000},
gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
graphiteReporter: {enabled: false, interval: 180000}}
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
Ii would be greatful if someone can tell me what i'm doing wrong here. Thanks.
The server log output might be showing the error that points you to the problem but my guess is that you're trying to connect with a driver serializer configuration that isn't getting recognized by the server and it therefore defaults to GraphSON 3.0 serialization. That change happened a long time ago, way back on TINKERPOP-1565 for the 3.3.0 release.
When we started pushing GraphSON 3.0 we wanted it to be the default JSON based network serialization format, so we gave it the "application/json" mime type which formerly went to untyped GraphSON 1.0. So, you need a bit of a custom configuration to make the driver and server recognized what you want to have happen:
gremlin> cluster = Cluster.build().serializer(new GraphSONMessageSerializerV1d0()).create()
==>localhost/127.0.0.1:8182
gremlin> client = cluster.connect()
==>org.apache.tinkerpop.gremlin.driver.Client$ClusteredClient#277b8fa4
gremlin> x = client.submit("[1,2,3]").all().get()
==>result{object=1 class=java.lang.Integer}
==>result{object=2 class=java.lang.Integer}
==>result{object=3 class=java.lang.Integer}
You can see that you have to explicitly build the GraphSONMessageSerializerV1d0 (and in your case you would likely add the JanusGraphIoRegistry manually to that by using the constructor that takes a GraphSONMapper.
All that said, while GraphSON 1.0 isn't going anywhere it's curious that you would need to utilize it directly. Unless you have a really good reason to do so, I'd highly recommend that you stick to GraphSON 3.0. It has the widest support among graph providers is about as fast as Gryo these days for most serialization operations. If you're exclusively on the JVM, I'd even suggest trying GraphBinary rather than going back to GraphSON 1.0.
I am trying to create a simple IAM role to have my AppSync service connect to my DynamoDb database, but because AppSync is in preview, IAM does not recognize AppSync as a service. How do I create an IAM role for to let AppSync have full access to DynamoDb?
The trusted relationships side looks something like this
Example Trusted Relationships Doc
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
The policy doc is basically the same as always
Example Policy Doc
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
If you are using a CloudFormation template, it might look like this
Example CloudFormation Template
AppSyncRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "appsync.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
-
PolicyName: "appsync-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "dynamodb:PutItem"
- "dynamodb:UpdateItem"
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:Query"
- "dynamodb:Scan"
Resource: "*"
If I have a domain name www.domain.com registered and I have fresh kubernetes cluster up and running. I have successfully lauched Deployments and Services to expose the requirements.
The service is creating a LoadBalancer on my GCE cluster and when I try to access my APP through the the external IP its working.
But this is what I wanted to achieve ideally :
To route all the traffic for my apps as www.app.domain.com , www.app2.domain.com. Upon research I have found that I need an Ingress Controller preferably NGINX server, I have been try to do this and failing miserably.
This is the service exposing JSON for my deployments:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": 'node-js-srv'
},
"spec": {
"type": 'LoadBalancer',
"label": {
'app': 'node-js-srv'
},
"ports": [
{
"targetPort": 8080,
"protocol": "TCP",
"port": 80,
"name": "http"
},
{
"protocol": "TCP",
"port": 443,
"name": "https",
"targetPort": 8080
}
],
"selector": {
"app": 'node-js'
},
}
}
GCE/GKE have already a Ingress Controller and you could use that one.
You must specify your service as type NodePortand create a ressource from type Ingress
See:
https://kubernetes.io/docs/user-guide/ingress/
You find a example for GCE here https://github.com/kubernetes/ingress/tree/master/examples/deployment/gce
Service:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": 'node-js-srv'
},
"spec": {
"type": 'NodePort',
"label": {
'app': 'node-js-srv'
},
"ports": [
{
"targetPort": 8080,
"protocol": "TCP",
"port": 80,
"name": "http"
},
{
"protocol": "TCP",
"port": 443,
"name": "https",
"targetPort": 8080
}
],
"selector": {
"app": 'node-js'
},
}
}
Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: www.app.domain.com
http:
paths:
- backend:
serviceName: node-js-srv
servicePort: 80
- host: www.app2.domain.com
http:
paths:
- backend:
serviceName: xyz
servicePort: 80
I'm developing a RESTful service with Symfony2, JMS Serializer Bundle, FOS Rest Bundle and Hateoas Bundle. There are 2 entities User and Company and I want to, when I serialize a Company get larger detail.
But, when serializing User related Company show only Company ID and name object or just ID as integer.
I have serialize policy like below.
User
Acme\UserBundle\Entity\User:
exclusion_policy: ALL
xml_root_name: user
properties:
id:
expose: true
type: integer
company:
expose: true
type: Acme\CompanyBundle\Entity\Company
name:
expose: true
type: string
surname:
expose: true
type: string
picture:
expose: true
type: string
relations:
-
rel: self
href:
route: acme_v1_get_user
parameters:
id: expr(object.getId())
absolute: true
Company
Acme\CompanyBundle\Entity\Company:
exclusion_policy: ALL
xml_root_name: company
properties:
id:
expose: true
type: integer
name:
expose: true
type: string
address:
expose: true
type: string
phone:
expose: true
type: string
web:
expose: true
type: string
created_date:
expose: true
type: DateTime
updated_date:
expose: true
type: DateTime
status:
expose: true
type: integer
relations:
-
rel: self
href:
route: acme_v1_get_company
parameters:
id: expr(object.getId())
absolute: true
Expected output
{
"id": 1,
"name": "Jenny",
"surname": "Doe",
"picture": "http://google.com/kittens.jpg",
"info": [],
"company": {
"id": 1,
"name": "Demo Company"
}
}
OR
{
"id": 1,
"name": "Jenny",
"surname": "Doe",
"picture": "http://google.com/kittens.jpg",
"info": [],
"company": 1
}
What I got
{
"id": 1,
"name": "Jenny",
"surname": "Doe",
"picture": "http://google.com/kittens.jpg",
"info": [],
"company": {
"id": 1,
"name": "Demo Company",
"address": "Lorem ipsum dolor sit amet",
"phone": "0902124440444",
"web": "http://www.demo-company.com",
"created_date": "2015-07-22T11:21:03+0300",
"updated_date": "2015-07-24T01:50:39+0300",
"status": 1
}
}
You can use groups
AppBundle\Entity\User\User:
exclusion_policy: ALL
properties:
lastname:
expose: true
groups: [info]
And with an annotation, you can define which property is displayed on which group. And finally, you can assign a group to every route you use.
Or you can use virtual properties like so :
AppBundle\Entity\User\User:
exclusion_policy: ALL
properties:
[…]
virtual_properties:
getCompanyId:
serialized_name: company
type: string
groups: [info]
And you create a getCompanyId() method in your User entity, that returns the companyId
The more Hateoas way to do it would be with the relations.
Acme\UserBundle\Entity\User:
exclusion_policy: ALL
xml_root_name: user
properties:
id:
expose: true
type: integer
name:
expose: true
type: string
surname:
expose: true
type: string
picture:
expose: true
type: string
relations:
-
rel: self
href:
route: acme_v1_get_user
parameters:
id: expr(object.getId())
absolute: true
-
rel: company
href:
route: acme_v1_get_company
parameters:
id: expr(object.getCompany().getId())
absolute: true
Would yield...
{
"id": 1,
"name": "Jenny",
"surname": "Doe",
"picture": "http://google.com/kittens.jpg",
"info": []
"_links": {
"self": {
"href": "http://server.com/api/user/1"
},
"company": {
"href": "http://server.com/api/company/1"
},
}
}