How to create a compound object in a REST API - php

I'm creating a REST API for my application, and I have a doubt about how to design my API, following REST principles. I'm using PHP and Lumen, but I guess it's more a design doubt than a technical one.
Consider I have two entities:
Company:
- id
- name
User:
- id
- name
- email
- company_id
Each Company must have one or more User's, and I'd like to assert that rule in my API. As far as I've understood REST specifications, I should create one endpoint for each entity, so the API client should make a POST to http:\\myserver\api\company to include a company, and after that make another POST to http:\\myserver\api\company\{id}\users to include a User in the new Company. The problem with that approach is that the client could only create a Company and leave it without User's.
In a non-rest API, I could create a method called createNewUser, which would receive the user's data together with Companydata, and this method would ensure that both entities are created.
How could I achieve that in a REST API?

I have a doubt about how to design my API, following REST principles.
Part of the problem here could be the confusing messages you are getting about "REST principles".
Consider how you might do this on the web. You want somebody to give you both user data and company data. So you would create a web page with a form; some of the form controls would be designed to collect user data, some would be designed to collect company data. When the form is submitted, the browser would copy the information from the forms input controls into an application/x-www-form-urlencoded request body, and POST it to the target URI specified in the metadata of the form. Ta-da.
That's REST.
Is that the only answer that's REST? No. Equally RESTful would be to have clients write the user and company data into a local document, and then save a copy of that document on the web server. Or to download a document from the web server, edit the user and company data into the local copy, then save the revised document on the server. Or to send a patch document describing the edits to the web server, and allow the server to compute the changes to its own copy of the document.
All of these are fine.
as I've understood REST specifications, I should create one endpoint for each entity,
This is where you are getting derailed (not your fault, the literature sucks)
REST doesn't have endpoints, it has resources
HTTP requests target resources, not entities
"different entity therefore different resource" is not a constraint that comes from REST.
Fine grained resources work well in some cases (in particular they are a good fit for copying information into an anemic data model), but they aren't universal. In a context where fine grained resources don't work well... design your resource model differently.

Related

Getting an Embed Token for App Owns Data model in Power BI

I've been working through how to implement getting a Power BI Embed token for the App Owns data model in Power BI. It's proving a little tricky
I've found a post: https://www.msbiblog.com/2018/01/12/power-bi-embedded-example-using-curl-and-php/
Which has helped but translating this into app owns data but I feel that I am missing a small but important point somewhere
Does anyone have ideas or code examples that will help put some light on this
thanks
It's not very clear what are you missing, but here are the official samples from Microsoft, including the demo how to implement App owns data scenario. A good place to start is to read Embed content in your application for your customers tutorial. You can see how things work in the playground demo.
To embed Power BI element in your application, you need to do the following:
Register an application - go to dev.powerbi.com/apps and register a native application. Select which permissions to grant it (if you aren't sure, for your first tests simply grant them all). Copy the guid - this is the app ID, a.k.a. client ID.
Next step is to authenticate from your application and get an access token. Use Azure Active Directory Authentication Library (ADAL) for that - call some of the acquireToken methods of AuthenticationContext class. Here is one ADAL client library for PHP, and here is Microsoft's documentation for these methods.
Use this access token to call the Power BI REST API and get the embedUrl of the element you want to embed, e.g. report.
Use Power BI JavaScript client to actually embed this element. You need to initialize one embed configuration class and pass information about element type (report, dashboard, tile), where to find it (embedUrl), authentication (access token), some other configuration options (show or hide filters pane, navigation, etc.), filters to be applied and so on. In case you will use the access token acquired above, set tokenType to be AAD. This token has many privileges, so for security reasons you may want to use Embed token instead. In this case use the access token to call the REST API again (e.g. Reports GenerateTokenInGroup).
Call powerbi.embed method of the JavaScript client pass the embedded configuration to visualize this Power BI element in your app.
I will recommend you also to take a look at Embedding basics article (and the rest of the articles in this wiki).

passing user information from php to django

I am building a web app in django and I want to integrate it with the php web app that my friend has build.
Php web app is like forum where students can ask question to the teachers. For this they have to log in.
And I am making a app in django that displays a list of colleges and every college has information about teachers like the workshop/classes timing of the teachers. In my django app colleges can make their account and provide information about workshop/classes of the teachers.
Now what I want is the student that are registered to php web app can book for the workshop/classes provided by colleges in django app and colleges can see which students and how many students have booked for the workshop/classes.
Here how can I get information of students from php web app to django so that colleges can see which students have booked for workshop. Students cannot book for workshop untill they are logged in to php web app.
Please give me any idea about this.. How can I make this possible
You must use one of these possibilities:
Your friend gives you direct access (even only read access) to his database and you represent everything as Django models or use raw SQL. The problem with that approach is that you have a very high-coupling between the two systems. If he changes his table or scheme structure for some reason you will also have to be notified and change stuff on your end. Which is a real headache.
Your friend provides an API end-point from his system that you can access. This protocol can be simple GET requests to retrieve information that return JSON or any other format that suites you both. That's the simplest and best approach for the long run.
You can "fetch" content directly from his site, that returns raw HTML for every request, and then you can scrape the response you receive. That's also a headache in case he changes his site structure, and you'll need to be aware of that.
If you cannot get the data from database directly then ask your friend to implement URL alike /students_info?book=bookname that returns in JSON format list of the students that ordered mentioned book.
In your python app
import urllib, json
url = "the url to php app/students_info?book=bookname"
response = urllib.urlopen(url);
data = json.loads(response.read())
You could try with REST, ie: Django rest framework and create a web API. By this way, you could send JSON data between Django and PHP.

How to handle PUT and DELETE HTTP request in a PHP API First App?

I am wanting to build an API first RESTful application in PHP. I have never attempted to do this so I have some questions about how to handle PUT and DELETE
So for an example if I have a API endpoint that updates a User profile, should I make it accept BOTH a POST and PUT Request?
If I was building a Client for my API as a Desktop app or iOS app, etc it would be easy to send a PUT request to my API but I plan to have a Web based app for my API as well.
So on my web based app, I would have an HTML Form to Update a User profile, this would then be sent as a POST as HTML Forms do not allow PUT requests.
Could someone with more experience with this explain the best way to handle my example scenario?
Would the proper way be to send my Form as a POST to my PHP script, then my PHP script would make a proper PUT request to my PHP API with cURL?
You can absolutely also do PUT requests from browsers, but you need javascript.
Generally I would say a good way to think about it, is as follows:
First build a great REST api that follows all the rules. Only once you are at that point, think about the workarounds you need to make it work in other contexts. Submitting an HTML form is a valid thing to need a workaround for.
However, since 'POST' is completely open for interpretation, and has little rules associated, one option would be to create a single resource (or url) on your server that handles all the POST requests coming from browsers. (something like /browserpost).
You could always add a hidden <input> field with name="url" that specifies which resource was actually intended to be updated, and an <input> with name="method" value="PUT" for the intention.
You will need to add CSRF protection anyway, so I feel this would be a solid way to deal with this this. 1 endpoint to specifically 'proxy' html-based form submissions and internally do the appropriate mappings to the correct REST services.
I would use GET POST PUT DELETE as they are described in HTTP. That's restful (in my opinion). As regular browser forms does not support this I would send the data via AJAX.
If you really need to use browser forms, maybe because javascript is not enabled, then using POST requests with a param like ?method sounds like a suitable solution - although I don't like it.

Role Based Security in JavaScript in RIA

I'm trying to learn the development of Web Applications in JavaScript, and for this I am developing a simple Time Tracking application. I am developing this with ExtJS for dynamically creating the UI.
This would allow Employees to submit the time they have spent working on different projects, and allow the Managers, to add Projects to Users and so on.
Once the user signs in, I determine their role, and provide the appropriate UI (through JavaScript).
I was wondering what is the best and most secure way of doing this? (I am of course checking the authorization on the server side, so that no one can make changes by just calling my PHP Services via http get/post)
I asking from a perspective of disallowing a non authorized person, to even see the non-authorized UI, by fiddling with the JavaScript (from the FireBug console for example).
I was thinking of creating a Service which returns the appropriate script for creating the appropriate UI, through JSONP. It feels quite WTF-ey to me, so I was wondering if there was better way.
To build on naugtur's comment. You must always assume that there will be a very smart person that can build the UI for himself/herself, or fake any of the calls to the server that any part of the UI could do.
Based on that, the premise of the way you suggested towards the end of your question seems debunk to begin with. The easiest route once we settle that (I'm assuming your making a single-page application) would be to always dump all the javascript code right up front at the login screen and only allow the user to see what they need to based on their role (i.e. a card panel that has different cards for each role would be an example).
I would also like to add that on the backend of the application, you should always have security checks in place to make sure the user has the correct role for whatever action he is doing. If your application is internet facing, this is a necessity, there will always be that user who will look through your code and see what he can do maliciously or just for fun... or that guy on who wants to see what happens when he uses the debugger to create his own fake ajax calls with varying parameters.

Remote alternative to local storage for low-security user data?

Suppose you're developing an independent, small sub-page for a big and well frequented web portal.
The sub-page shows entries from a public event calendar, and allows users to highlight those especially interesting to them. The highlighted events shall be highlighted (and maybe shown on a separate list) on each future visit of that user.
However, building a classical user registration system, or any other way of storing the user-highlighted event picks on the server, is not an option: The sub-module needs to be as self-contained and need as little maintenance as possible. It's one of the conditions of the project.
The only way to do this without building a login system of some sort (as far as I can see) is using cookies or some other local storage (Flash / HTML 5....) which has the obvious and big downside that it's tied to the computer, not the user.
Is there a way of storing a few kilobytes data on a per-person basis, but without having to utilize a login or openID, that I am overlooking? A reliable web service perhaps?
A "key/value" storage service, to which I pass a unique key (one that the user specified) and get the savedvalue in return, would be sufficient. There is no need for real security - the data in question is by no means confidential.
OpenID is not an option: It is not well known enough among the audience of the site.
Facebook would be an option, but I don't think they provide "storage" options like this.
As a workaround, I am contemplating offering the user their event picks as a text file download, that also can be uploaded and turned into cookies on another machine. But that is pretty complicated for the user, and thus not perfect.
We have a similar system on our site, where users can bookmark pages to a planner/wishlist function. The saved items are sent via a webservice and stored on our server, and there is a corresponding get webservice.
We have a 'lazy register' system. The first time a user saves an item, they are asked for their email (but no password, as nothing is confidential). This is hashed and saved locally using a cookie, then used to set/get the saved items. When the user uses a different computer they are again asked for their email.
The key is that a register and a login are the same operation, so there is no need for any password reminders or any reset functionality.
The Google Docs API provides programmatic access to Google Docs, where you can create and store documents and spreadsheets. Your application could have its own Google login, which it uses to create one or more documents per user. These documents could be used to store the user settings.
Provided you can get a unique ID from each user (an email address, or something more secure, perhaps), this should be fairly simple. You can even organize the files into folders—one per user.
Alternatively, you could combine Google Docs with the Google Spreadsheets API, where I have just noticed this rather handy feature:
Tables & Records
Interact with spreadsheets as if they're a database
using Tables and Records.

Categories