How can i write this JSON swagger-php below with annotations? - symfony

I'm using OpenAPI 3.0 to document my Symfony API. this is the JSON code that authenticates the user to send requests:
"securitySchemes": {
"Bearer": {
"type": "http",
"description": "Entrer le token JST",
"scheme": "bearer",
"bearerFormat": "JWT"
}
}
},
"security": [
{
"Bearer": []
}
]
How can i write this with annotations in controller ?
thanks

You almost can; currently swagger-php does not support the bearerFormat property.
=> https://github.com/zircote/swagger-php/issues/1258
The rest would look something like this globally.
/**
* #OA\SecurityScheme(
* securityScheme="bearerAuth",
* type="http",
* scheme="bearer",
* description="Entrer le token JST"
* )
*/
For a controller to require security you'd add this:
/**
* #OA\Get(
* path="/api/endpoint",
* ...
* security={{ "bearerAuth": {} }}
* )
*/

Related

Save entity with subresource into redis with Symfony & Api Platform

I have 2 entities, Event & User. So basically A user can have multiple event.
I have an EventItemDataProvider and in the getItem method I did something like that:
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Event
{
if ($event = $this->cache->get($id, Event::class)) {
return $event;
}
$event = $this->em->getRepository(Event::class)->find($id);
if($event) {
$this->cache->set($id, $event, 120);
}
return $event;
}
When the data is returned without the cache I have this result that is correct with the right username:
{
"#context": "/contexts/Event",
"#id": "/events/20",
"#type": "Event",
"title": "new global event 3",
"description": "A big global event 3",
"createdAt": "2019-07-05T09:20:48+00:00",
"owner": {
"#id": "/users/3",
"#type": "User",
"username": "test3"
}
}
But if I hit the same method a second time, it will retrieve the data from the cache (redis) but this time username will be empty like that:
{
"#context": "/contexts/Event",
"#id": "/events/20",
"#type": "Event",
"title": "new global event 3",
"description": "A big global event 3",
"createdAt": "2019-07-05T09:20:48+00:00",
"owner": {
"#id": "/users/3",
"#type": "User",
"username": ""
}
}
Why is my username empty when I retrieve it from redis?
Basically my cache class has these methods:
public function get(string $uniq, string $className)
{
$value = $this->cache->getItem('test_key')->get();
return $value;
}
public function set(string $uniq, object $entity, int $expires = 60)
{
$save = $this->cache->getItem('test_key');
$save->set($entity);
$save->expiresAfter($expires);
$saved = $this->cache->save($save);
return $saved;
}
The owner field in my Event entity:
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="events")
* #ORM\JoinColumn(nullable=false)
* #Groups({"event:read", "event:write", "event:update"})
* #Assert\Valid()
*/
private $owner;
The username field in my User entity:
/**
* #ORM\Column(type="string", length=25, unique=true)
* #Groups({"user:read", "user:write", "user:update", "event:item:get", "event:update"})
* #Assert\NotBlank(message="Please provide a username")
*/
private $username;
My redis cache configuration:
cache:
app: cache.adapter.redis
default_redis_provider: "redis://redis"
pools:
custom.cache.entity:
adapter: cache.app
default_lifetime: 120
Why my username is filled when I retrieve it from Doctrine Repository but empty when I retrieve it from Redis?
With Xdebug I can see that if I retrieve the data from Doctrine I have something like that:
But if I retrieve the data from the cache I have something like that:
In this second case, initializer -> this seems infinite, so I think that the problem is probably here, but what should I do to solve this issue?

Symfony4 JMS\Serializer\SerializedName will be ignored on deserialize()

I have a JSON that will be deserialize() with JMS.
The JSON looks like
{
"creator": [
{
"value": 234,
"label": "Hello"
},
{
"value": 223,
"label": "World"
}
]
}
The JSON will be deserialized with my created Model
$this->serializer->deserialize($json, Model::class, 'json');
and my Model class has:
/**
* #Serializer\Type("array")
*/
private $creator;
This works perfectly fine, the deserializer convert the JSON into my Model and I receive creator with array-items.
I would like to change the variable name from creator to customer in my model. I was thinking it works with the annotation #Serializer\SerializedName().
But when im using this
/**
* #Serializer\Type("array")
* #Serializer\SerializedName("customer")
*/
private $creator;
the model will be not filled at all.
Do I fundamentally misunderstand this function?

How to have absolute url with Hateoas Bundle on Symfony2

I just fresh installed the bundle from Willdurant's github and I got relative url like this:
"_links": {
"self": {
"href": "/1.0/users/?page=1&limit=10"
},
"first": {
"href": "/1.0/users/?page=1&limit=10"
},
"last": {
"href": "/1.0/users/?page=2&limit=10"
},
"next": {
"href": "/1.0/users/?page=2&limit=10"
}
}
For my Hateoas url, I really prefer absolute url but I don't find anything on google to change that. 2 hours of search, trying multiple keywords and nothing...
Thanks for your help.
You can use it many ways. All depends on the way of generating links.
If you use #Route annotation to generate link, it has a parameter absolute that need to be set to true:
/**
* #Hateoas\Relation(
* name = "self",
* href = #Hateoas\Route(
* "user_get",
* parameters = { "id" = "expr(object.getId())" },
* absolute = true
* )
* )
*/
If you use expression language to generate link you can pass true as third parameter to the link() function:
/**
* #Hateoas\Relation(
* "user",
* href = "expr(link(object.getUser(), 'self', true))"
* )
*/

JMS #Discriminator filed doesn't appear if specific group is serializing

I'm using Symfony 2.8, FOSRestBundle and JMSSerializerBundle.
Problem
Discriminator field type of Document entity doesn't apear in serialized model when I serialize specific group ("api" group in folowing example) of entity Citizen.
Doctrine Entities
Document:
namespace MyBundle\Entity;
use JMS\Serializer\Annotation as JMS;
…
/**
* #JMS\Discriminator(field = "type", map = {
* "doc1" = "MyBundle\Entity\Document1",
* "doc2" = "MyBundle\Entity\Document2"
* })
*/
class Document
…
Citizen:
class Citizen
{
…
/**
* #var ArrayCollection
*
* #ORM\OneToMany(
* targetEntity="MyBundle\Entity\Document",
* cascade={ "PERSIST", "REMOVE" },
* orphanRemoval=true,
* mappedBy="citizen"
* )
*
* #JMS\Groups({"api"})
*/
private $documents;
…
What I get
{
…
"documents": [
{
"number": "000000",
"date": "01.01.1970",
"serial": "0000",
"place": ""
}
],
…
}
What I need
{
…
"documents": [
{
"type": "doc1",
"number": "000000",
"date": "01.01.1970",
"serial": "0000",
"place": ""
}
],
…
}
If I remove specific serialization group, then type field is present in serialized output.
Thanks in advance
Just found issue on github.
Seems for now, workaround with Default group is needed, see lordelph's comment

Multiple links in Bazinga Hateoas with Symfony

I am using Bazinga Hateoas with Fosrest in one of my SF2 project.
In one of API call, I want to display link of friends with current user or user id supplied like this:
{
"_links": {
"self": { "href": "/users/1" },
"friends": [
{ "href": "/users/2" },
{ "href": "/users/3" },
]
},
}
I am using below code in Entity.User.yml file:
relations:
-
rel: self
href:
route: api_1_get_users
parameters:
id: expr(object.getId())
absolute: true
-
rel: expr(object.findFriends(object.getId()))
href:
route: api_1_get_users
parameters:
id: expr(object.getId())
absolute: true
I have put "findFriends" method in repository but its not accessible inside yml file. I guess this is not the correct way of doing things.
I have gone through https://github.com/willdurand/Hateoas but not able to figure out how to do it. Please guide me how I can achieve this...
Any help would be much appreciated !
Please guide me how I can achieve this
This is how you work with #RelationProvider.
/**
* Note:
* ====
* RelationProvider takes the method name which returns the relations.
*
* #Hateoas\RelationProvider("addRelations")
*/
class LinkContainingResource
{
public function addRelations($object, ClassMetadataInterface $classMetadata)
{
/**
* Important Note:
* ===============
* Relation is actually an Hateoas\Configuration\Relation object,
* NOT \Hateoas\Configuration\Annotation\Relation
*/
return [new Relation('relation_name', 'link1'),
new Relation('relation_name', 'link2'),
new Relation('relation_name', 'link3')];
}
}
Json/Hal Result:
{
"_links": {
"relation_name": [
{"href": "link1"},
{"href": "link2"},
{"href": "link3"}
]
}
}

Resources