Subsets of properties in a Swagger definition - php

I'm writing an API where I have a Controller that POSTs a new object, GETs it back and can PUT/PATCH updates to it. The problem is that there's a difference in properties between the two different actions. For example, when I POST a new object I want to ensure that the 'id' of it is returned so that it can be used to identify it for the GET/PUT/PATCH endpoints. It doesn't matter if it comes back via the GET (it's just a duplication of data at that point) but I certainly don't want it passed for the PUT or PATCH as the id is immutable.
So what's the best way to mark this up in swagger so that I can have different versions of the same Definition? I've seen that you can use 'allOf' to add Definitions to other properties, but I'm wondering if there's a way of saying 'not these properties in the definition'?
If I could do the latter I could make one Definition of the object as a whole and simply knock out the things that aren't required to be returned or submitted when referencing it at the Controller. Is this possible? Am I making sense?
(Just to make things more interesting, my swagger.json file is being generated by swagger-php based on Annotations in my controller and entity files)

I am facing the same issue while writing our spec file, and didn't know how to fix it but what I used is the property "readOnly":true, this way the documentation says that this is a readonly property, you can only read it through GET/POST methods but you cannot send it via PATCH/ PUT.. hope this helps

Related

Which is best practice? Identity type or setting a dynamic property runtime?

While designing a class I assumed that having an $id property will make that class Entity rather than a value object.
I also have a toArray() method which converts the object to associative array and that response is send to post and patch api's.
Now I have the following questions:
POST works,
since I’m not sending the id in the body. But for PATCH is it fine if I set the property dynamically after object creation? For Ex:
$redCircle = new Circle(“red”);
$redCircle->id = 10;
$api->patch($redCircle->toArray());
Your point of view is very technical, as opposed to DDD.
You should design your Aggregates and nested Entities according to the business rules (the invariants).
While designing a class I assumed that having an $id property will make that class Entity rather than a value object.
This is not true. There are cases when a local Value object (that comes from a remote Aggregate, in another Bounded context) needs an ID property in order to be kept up-to-date (i.e. by background tasks). The Anti-corruption layer would need this property, so the reasons are pure technical.
POST works, since I’m not sending the id in the body. But for PATCH is it fine if I set the property dynamically after object creation?
Again, this is not a DDD view of the problem. In DDD, an Aggregate execute commands: one does not simply update its internal state directly; this would break its encapsulation.
But to answer your question, considering that you have a CRUD app: In order to mutate parts of an Entity you would need to load it from the Repository before mutation. The Repository would set the ID along with the other properties.
One of the best ways to locate entities is to use a RESTful API, so the client would not need to construct the URLs for the PATCH operation.

need to switch between class scopes

I have a class (PersistenceClass), that takes an array of data (posts) and parses that data and puts it into a DB (via doctrine). The field content needs to be parsed by a second class (SyntaxClass) before it is set into the doctrine entity.
Now the problem is, that the SyntaxClass has to set references in the content to other posts (just a link with and ID). So it needs access to the DB, and also needs to search in the persisted but not yet flushed entities from the PersistenceClass.
I can inject a doctrine EM into SyntaxClass and find my references in DB, although I dont like it very much. But the bigger problem is, how I can access the only persisted, but not flushed entities from the PersistenceClass ? I could make an Array of that objects and put it as an parameter to the parser method like:
SyntaxClass->parseSyntax($content, $persistedObjects);
But that does not look very clean. Aside from that, I dont know if it is somehow possible to search in the data of the persisted objects?
Your question is full of sub-question, so, first I'll try to make some things clear.
First, the naming convention you used is a bit abiguos and this not helps, me and also other people that may work on your code in future (maybe you'll grow and need to hire more developers! :P ). So, let's start with some nomenclature.
What you are calling PersistenceClass may be something like this:
class PersistenceClass
{
public function parse(array $posts)
{
foreach ($posts as $post) {
// 1. Parse $post
// 2. Parse content with SyntaxClass
// 3. Persist $post in the database
}
}
}
The same applies also for SyntaxClass: it receives the $content and parses it in some ways, then sets the references and then persists.
This is just to set some boundaries.
Now, go to your questions.
I can inject a doctrine EM into SyntaxClass and find my references in
DB, although I dont like it very much.
This is exactly what you have to do! The OOP development works this way.
But, and here come the problems with naming conventions, the way you inject the entity manager depends on the structure of your classes.
A good design should use services.
So, what currently are PersistenceClass and SyntaxClass in reality should be called PersistenceService and SyntaxService (also if I prefere call them PersistenceManager and SyntaxManager, because in my code I always distinguish between managers and handlers - but this is a convention of mine, so I'll not write more about it here).
Now, another wrong thing that I'm imaging you are doing (only reading your question, I'M IMAGING!): you are instantiating SyntaxService (you currently named SyntaxClass) from inside PersistenceService (your currently named PersistenceClass). This is wrong.
If you need a fresh instance of SyntaxService for each post, then you should use a factory class (say SyntaxFactory), so calling SyntaxFactory::create() you'll get a fresh instance of SyntaxService. Is the factory itself that injects the entity manager in the newly created SyntaxClass.
If you don't need a fresh instance each, time, instead, you'll declare SyntaxClass simply as a service and will pass it to PersistenceService by injection. Below this last simpler example:
# app/config/service.yml
services:
app.service.persistence:
class: ...\PersistenceService
# Pass the SyntaxInstance directly or a factory if you need one
aguments: ["#doctrine.orm.default_entity_manager", "#app.service.syntax"]
app.service.syntax:
class: ...\SyntaxService
aguments: ["#doctrine.orm.default_entity_manager"]
But the bigger problem is, how I can access the only persisted, but
not flushed entities from the PersistenceClass ?
Now the second question: how to search for {persisted + flushed} and {persisted + not flushed} entities?
The problem is that you cannot use the ID as the search parameter as the persisted but not flushed entities doesn't have one before the flushing.
The solution may be to create another service: SearchReferencesService. In it you'll inject the entity manager too (as shown before).
So this class has a method search() that does the search.
To search for the entities persisted but not flushed, the UnitOfWork gives you some interesting methods: getScheduledEntityInsertions(), getScheduledEntityUpdates(), getScheduledEntityDeletions(), getScheduledCollectionDeletions() and getScheduledCollectionUpdates().
The array of which you are speaking about is already there: you need to only cycle it and compare object by object, basing the search on fields other than the ID one (as it doesn't exist yet).
Unfortunately, as you didn't provided more details about the nature of your search, it is not possible for me to be more precise about how to do this search, but only tell you you have to search using the unit of work and connecting to the database if null results are returned by the first search. Also the order in which you'll do this search (before in the database and then in the unit of work or viceversa) is up to you.
Hope this will help.

MVC - Request Class

I have been trying to figure out if the request object should handle sorting out the controller and action or if that should be left up to the router? What I mean is that when the request object is passed to the router, if it should already contain the properties for the controller and action. Forgive me if this has been answered before but I couldn't find anything specific to this topic.
Most of the content I have found on this doesn't even use a request object. I know I could download a framework and look but I figure it might be just as easy to ask here.
This is very different in many Frameworks, but the basics are similar to this:
The Request Object (or any other kind of container for the passed input data) should only have this one responsibility: Containing the input (and sometimes result) data.
A specific other object (Called "Front Controller" in many frameworks) should sort out what controller and action to be called and nothing else.
This logic usually continues with the actuall called controller that only has the responsibility of selecting the correct model, and the model of only handling the data. Some frameworks split this even further.
But the theory is allways same: Each part of your app should only have to focus on one single task.
The link from #teresko above tells you the theory behind this: http://en.wikipedia.org/wiki/Single_responsibility_principle

Doctrine2 Define properties via magic methods

Using Doctrine, is it possible to map to properties which don't actually exist using magic methods?
I'm doing the mapping with YAML.
For example, if I wanted to map to a property named "demo", but SomeClass::$demo didn't actually exist. I'd want to some combination of __get(), __set(), __isset() and __call() to handle $demo (and getDemo() and setDemo()) and do something else with them.
I've tried setting this up, but I'm getting an error:
Uncaught exception 'ReflectionException' with message 'Property My\Bundle\DemoBundle\Entity\SomeClass::$demo does not exist'
I'm not sure if there is something special with the ReflectionProperty that causes it to miss my magic methods, or if I'm maybe missing a magic function. However, as far as I can tell, ReflectionProperty should interact with them.
Any ideas?
UPDATE:
Upon further investigation, it looks like the ReflectionProperty constructor will throw an exception and won't trigger the magic methods.
Does anyone else know of means to map Doctrine to dynamic properties?
Thanks.
UPDATE 2:
To example what I'm trying to accomplish.
Basically, I have a generic User object which just contains the base properties needed to handle actually being a user (roles, password, salt, username, etc.). However, I want to be able to extend this object to add application-and-user-specific meta data.
So, say I create a Forum bundle. I could then I could dynamically hook up meta data related to the user for use with the Forum. I don't want to put it directly in the User bundle, because then the User bundle becomes less flexible.
If I could somehow dynamically inject new data in to the user, it could all be loaded in a single query with the user, instead of having to be loaded in a separate query. I know there are some other methods to do this, which I've already explored and even used to a limited extend. However, it'd be much nicer if I could dynamically create these associations, which really shouldn't be that difficult of a leap.
If you don't need to search on these dynamic properties then just add a property called data to your entity and map it to a doctrine array type. Now do your majic stuff and store the dynamic properties in the data array.
A second approach might be along these lines: http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html. For each installation you might be able to give the administrators of making a custom entity.
But as long as you don't need to directly query on your dynamic properties then the first method works well.

ideas for simple objects for day to day web-dev use?

Dang-I know this is a subjective question so will probably get booted off/locked, but I'll try anyway, because I don't know where else to ask (feel free to point me to a better place to ask this!)
I'm just wrapping my head around oop with PHP, but I'm still not using frameworks or anything.
I'd like to create several small simple objects that I could use in my own websites to better get a feel for them.
Can anyone recommend a list or a resource that could point me to say 10 day-to-day objects that people would use in basic websites?
The reason I'm asking is because I'm confusing myself a bit. For example, I was thinking of a "database connection" object, but then I'm just thinking that is just a function, and not really an "object"??
So the question is:
What are some examples of objects used in basic PHP websites (not including "shopping cart" type websites)
Thanks!
Here's a few basic reusable objects you might have:
Session (identified by a cookie, stored server side)
User (username, password, etc.)
DBConnection (yes, this can be an object)
Comment (allow users to comment on things)
It sounds like you want to start to build your own web framework, which is a decent way to learn. Don't reinvent the wheel though. For a production site, you're probably better off using an existing framework.
Since you said you don't want to glue HTML and CSS again, you don't try this:
Create a WebForm class. This class is a container of form elements. It has methods to add and remove form elements. It has a getHTML() method that writes the form so that the user can input data. The same object is when a POST is made. It has a method to validate the input of the user; it delegates the validation to every form element and then does some kind of global validation. It has a process method that processes the form. It is final and checks whether validation has passed. If it passed it calls an abstract protected method that actually does the form-specific processing (e.g. insert rows into the DB). The form may be stored in the stored in session, or it may be re-built everytime (if it is stored in the session, it's easier to make multi-page forms).
Create a BaseFormElement and then several child classes like EmailElement, PhoneElement etc. These have also a getHTML() method that is called by WebForm::getHTML() and that prints the specific element. They have a validate() method that is called by WebForm::validate() and a getData() method that returns the properly validated and processed data of that element.
These are just some ideas. Some things may not make sense :p
I'd say database access would be the first most likely object - encapsulate your most common SQL requests into one class. If you make them abstract enough, you can use them for a wide variety of data access situations.
The way to think about class design/usage is to think of the class responsibility. You should be able to describe the class purpose in a short sentence (shorter than this...) i.e for database access object, you might say:
"provides API for common data access tasks"
If any of the methods in your data access class do something other than that, then you know they belong somewhere else.

Categories