Using numerous tutorials on Vapor 3 I've failed to figure out how I can edit output JSON, f.e. to get particular User object I create route:
protectedRouter.get("users", User.parameter, use: userController.user)
And method in UserController:
func user(_ req: Request) throws -> Future<User> {
return try req.parameters.next(User.self)
}
And it, of course, sends everything that inside the User object, including email and hashed password. Great. How can I avoid this? I mean I want to send only public information about the user (name, nick, id etc...).
Create a separate struct representing your desired output structure. Conform that struct to Content. Whenever you return your User, convert it to that struct first. Adding an extension to User that does this is nice for convenience.
A common pattern emerging is to nest this struct inside the Model calling it Public. i.e.,
extension User {
struct Public: Content { ... }
func makePublic() -> Public { ... }
}
Your routes would then return User.Public instead of User. Note that this pattern is also useful in reverse, for creating a separate "input" representation for your User.
You can read more about this in Vapor's docs at Vapor → Content → Dynamic Properties.
Related
How to use this <Label>k__BackingField: "Aachi" type of data value in ionic?
enter image description here
I am getting this response in the ionic rest API response. API made in ASP .net.
Here is a working example.
export interface YourInterface {
"<Label>k__BackingField": string;
}
let value: YourInterface = { '<Label>k__BackingField': 'Aachi' };
console.log(value['<Label>k__BackingField']); // Outputs 'Aachi'
However, I would recommand renaming/mapping the properties so you can access them with . instead of []. For example, you can have an interface for your raw API response, another interface with 'valid' property names, and a function that converts one to the other, and/or vice versa if needed.
I'm curious what is the best way of returning the same resource but using different DTOs.
For example, I have a user class:
public class User {
private String name;
private String surname;
private String age;
}
The list of users is available under url:
/users
Some other view needs list of users but without age, so, I would like to return list of UserDTO.
public class UserDTO {
private String name;
private String surname;
}
What is the proper way of defining url?
/userDtos - this is bad, because I can have more than one DTOs for representing users,
/users/dto - this is also bad
/users?name=true,surname=true - this one is also bad, it indicates that we are filtering the result, but we are not; we're just filtering fields.
For sure someone already had this problem before, but I couldn't find anything on the Internet.
A similar concept is called partial response which provide an option to let client to specify which fields to include in the response using the query parameters like:
:
/user?fields=name,surename
Basically you define a syntax for you own query language to represent a selection of fields. Here and Google Cloud API are some examples.
By taking this concept to a more coarse-grained level , you can use query parameter "view" to define different predefined combination of fields such as:
/users //default view if no "view" query parameter is specified
/users?view=admin //maybe this view will not show age field
/users?view=hr //maybe this view only show the fields that are accessible to HR
so I already finished all of the actual app for this. I just need to setup the backend. I figured Firebase was the best solution since Parse is no longer a thing. What I wanted was:
Users with profiles - These profiles can be viewed by added friends but only edited (written) to by the actual profile owner.
So I read through the Firebase Docs and still cannot really figure out how to do this. They only have 1 Swift application example that does not do anything similar and the one Obj C twitter one, will not even build. All of their docs still have println for Swift which just makes me think it is not updated frequently.
Does anyone have any good examples / tutorials of this? I keep trying to search for things but nothing is as similar enough to what I want. I am more looking on how to setup the db for each user and access it rather actually using Firebase in Swift.
As I wrote in my comment to your question, this answer is based on what we do in a real social app Impether using Swift + Firebase.
Data structure
Let's assume that you want to store the following information for a single user:
email
username
name
followers - number of people who follow a particular user
following - number of people who a particular user follows
avatar_url - url of their avatar
bio - some additional text
Since in Firebase everything is stored a JSON objects, you can store the above structure under node with path like users/$userId, where $userId is Firebase User UID which is created for each registered user if you use simple email/password Firebase authorization.
Firebase email/password authorization is described in their docs:
https://www.firebase.com/docs/ios/guide/user-auth.html
https://www.firebase.com/docs/ios/guide/login/password.html
Notice that there are both Obj-C and Swift snippets. I find Firebase documentation really great as it helped me a lot when I was building our app.
For the purpose of this answer let's assume that we have user with username jack and Firebase User UID equal to jack_uid (in reality this will be a string generated by Firebase).
Then an example data for this user will be store under a path users/jack_uid and can look like this:
{
"email" : "jack#example.com",
"username" : "jack",
"name" : "Jack",
"followers" : 8,
"following" : 11,
"avatar_url" : "http://yourstoragesystem.com/avatars/jack.jpg",
"bio" : "Blogger, YouTuber",
}
Firebase email/password authorization works really well, but let's be honest, if user wants to sign in into the app, it's a lot better for him to use his username than his email he gave while he registering his account.
In order to do that, we decided to store a mapping from usernames to user ids. The idea is that if user inputs his username and password in a login form, we use that mapping to retrieve his user id and then we try to sign him in using his user id and provided password.
The mapping can be stored for example under a path username_to_uid and looks like this:
{
"sample_username_1": "firebase_generated_userid_1",
"sample_username_2": "firebase_generated_userid_2",
...
"jack": "jack_uid",
"sample_username_123": "firebase_generated_userid_123"
}
Then creating a profile may looks like this and it's done as soon as registration of a new account was successful (this snippet is very close to the exact code we use in the production):
func createProfile(uid: String, email: String,
username: String, avatarUrl: String,
successBlock: () -> Void, errorBlock: () -> Void) {
//path to user data node
let userDataPath = "/users/\(uid)"
//path to user's username to uid mapping
let usernameToUidDataPath = "/username_to_uid/\(username)"
//you want to have JSON object representing user data
//and we do use our User Swift structures to do that
//but you can just create a raw JSON object here.
//name, avatarUrl, bio, followers and following are
//initialized with default values
let user = User(uid: uid, username: username, name: "",
avatarUrl: avatarUrl, bio: "",
followers: 0, following: 0)
//this produces a JSON object from User instance
var userData = user.serialize()
//we add email to JSON data, because we don't store
//it directly in our objects
userData["email"] = email
//we use fanoutObject to update both user data
//and username to uid mapping at the same time
//this is very convinient, because either both
//write are successful or in case of any error,
//nothing is written, so you avoid inconsistencies
//in you database. You can read more about that technique
//here: https://www.firebase.com/blog/2015-10-07-how-to-keep-your-data-consistent.html
var fanoutObject = [String:AnyObject]()
fanoutObject[userDataPath] = userData
fanoutObject[usernameToUidDataPath] = uid
let ref = Firebase(url: "https://YOUR-FIREBASE-URL.firebaseio.com/images")
ref.updateChildValues(fanoutObject, withCompletionBlock: {
err, snap in
if err == nil {
//call success call back if there were no errors
successBlock()
} else {
//handle error here
errorBlock()
}
})
}
In addition to this you possibly want to store for each user a list of his followers and a separate list of users he follows. This can be done just by storing user ids at a path like followers/jack_uid, for example it can look like this:
{
"firebase_generated_userid_4": true,
"firebase_generated_userid_14": true
}
This is the way we store sets of values in our app. It very convenient, because it is really user to update it and check if some value is there.
In order to count the number of followers, we put this counter into user's data directly. This makes reading the counter very efficient. However, updating this counter requires using transactional writes and the idea is almost exactly the same as in my answer here: Upvote/Downvote system within Swift via Firebase
Read/write permissions
A part of your question is how to handle permissions to data you store. The good news is that Firebase is exceptionally good here. If you go to your Firebase dashboard there is a tab named Security&Rules and this is the place where you control permissions to your data.
What's great about Firebase rules is that they are declarative, which makes them very easy to use and maintain. However, writing rules in pure JSON is not the best idea since it's quite hard to control them when you want to combine some atomic rules into a bigger rule or your app simple grows and there are more and more different data you store in your Firebase database. Fortunately, Firebase team wrote Bolt, which is a language in which you can write all rules you need very easily.
First of all I recommend to read Firebase docs about Security, especially how does permission to a node influences permission for its children. Then, you can take a look at Bolt here:
https://www.firebase.com/docs/security/bolt/guide.html
https://www.firebase.com/blog/2015-11-09-introducing-the-bolt-compiler.html
https://github.com/firebase/bolt/blob/master/docs/guide.md
For example, we use rules for managing users data similar to this:
//global helpers
isCurrentUser(userId) {
auth != null && auth.uid == userId;
}
isLogged() {
auth != null;
}
//custom types, you can extend them
//if you want to
type UserId extends String;
type Username extends String;
type AvatarUrl extends String;
type Email extends String;
type User {
avatar_url: AvatarUrl,
bio: String,
email: Email,
followers: Number,
following: Number,
name: String,
username: Username,
}
//user data rules
path /users/{$userId} is User {
write() { isCurrentUser($userId) }
read() { isLogged() }
}
//user's followers rules
//rules for users a particular
//user follows are similar
path /followers/{$userId} {
read() { isLogged() }
}
path /followers/{$userId}/{$followerId} is Boolean {
create() { isCurrentUser($followerId) && this == true }
delete() { isCurrentUser($followerId) }
}
//username to uid rules
path /username_to_uid {
read() { true }
}
path /username_to_uid/{$username} is UserId {
create() { isCurrentUser(this) }
}
The bottom line is that you write rules you want using Bolt, then you compile them into JSON using Bolt compiler and then you deploy them into your Firebase, using command line tools or by pasting them into dashboard, but command line is way more efficient. A nice additional feature is that you can test your rules by using tools in Simulator tab in your dashboard.
Summary
For me Firebase is a great tool for implementing a system you want. However, I recommend to start with simple features and learn how to use Firebase in the first place. Implementing social app with functionality like for example Instagram is quite a big challenge, especially if you want to do it right :) It's very tempting to put all functionality there very quickly and Firebase makes it relatively easy to do, but I recommend to be patient here.
In addition, take your time and invest in writing tools. For example, we have two separated Firebase databases, one for production and second for testing, which is really important if you want to write unit and UI tests efficiently.
Also, I recommend building permission rules from the beginning. Adding them later may be tempting, but also quite overwhelming.
Last but not least, follow Firebase blog. They post regularly and you can be up to date with their latest features and updates - this is how I learnt how to use concurrent writes using fanout technique.
I am using the Asp.Net Web Api. I would like to be able to filter out certain fields on the response objects based on the connected clients access rights.
Example:
class Foo
{
[AccessFilter("Uberlord")]
string Wibble { get; set; }
string Wobble { get; set; }
}
When returning data the filed Wibble should only be returned if the current users context can satisfy the value of "Uberlord".
There are three avenues that I am exploring but I have not got a working solution:
A custom WebApi MediaTypeFormatter.
A custom json.net IContractResolver.
Some sort of AOP wrapper for controllers that manipulates the response object
My issue with these are:
The custom formatter does not feel like the right place to do it but might be the only option.
The custom json serializer would not have access to the current context so I would have to work that out.
With the first two options you would require specific implementations for each response format, json, xml, some custom format, etc. This would mean that if another response type is supported then a custom formatter / serializer is required to prevent sensitive data leaking.
The AOP controller wrapper would require a lot of reflection.
An additional bonus would be to strip out values from the fields on an inbound request object using the same mechanism.
Have I missed an obvious hook? Has this been solved by another way?
It was actually a lot simpler than I first thought. What I did not realise is that the DelegatingHandler can be used to manipulate the response as well as the request in the Web Api Pipeline.
Lifecycle of an ASP.NET Web API Message
Delegating Handler
Delegating handlers are an extensibility point in the message pipeline allowing you to massage the Request before passing it on to the rest of the pipeline. The response message on its way back has to pass through the Delegating Handler as well, so any response can also be monitored/filtered/updated at this extensibility point.
Delegating Handlers if required, can bypass the rest of the pipeline too and send back and Http Response themselves.
Example
Here is an example implementation of a DelegatingHandler that can either manipulate the response object or replace it altogether.
public class ResponseDataFilterHandler : DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
//Manipulate content here
var content = response.Content as ObjectContent;
if (content != null && content.Value != null)
{
((SomeObject)content.Value).SomeProperty = null;
}
//Or replace the content
response.Content = new ObjectContent(typeof(object), new object(), new JsonMediaTypeFormatter());
return response;
});
}
}
Microsoft article on how to implement a delegating handler and add it to the pipeline.HTTP Message Handlers in ASP.NET Web API
I have a similar question in the works over here: ASP.NET WebAPI Conditional Serialization based on User Role
A proposed solution that I came up with is to have my ApiController inherit from a BaseApiController which overrides the Initalize function to set the appropriate formatter based on the user's role. I haven't decided if I will go this way yet, but perhaps it will work for you.
protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
// If the user is in a sensitive-data access role
controllerContext.Configuration.Formatters.Add(/*My Formatter*/);
// Otherwise use the default ones added in global app_start that defaults to remove sensitive data
}
I need to develop a pretty complicated Flash site based on the Facebook API, and if there's a way I can develop locally rather than having to upload it all the time I would be forever grateful.
I saw a post mentioning setting something to localhost but they never specified what exactly ( is it possible to use facebook API locally? )
Much appreciated.
Encapsulation is your friend in this case. When I use external / 3rd party APIs, I like to make a wrapper class of my own for the data. Let's say you only care about 'fbID' and 'userName'. Make a class of your own to hold this data once it is retrieved (private vars with getters, and 1 or more setters). Some skeleton code:
class MyUserClass{
//declare vars here (_fbID, _userName)
public function setData(userID:String, userName:String):void{
//set the values here.
}
//getters here (get fbID, get userName)
}
You can use 2 setter functions if you want to, but the point is that you will be able to call them with any data you want. When your entire application fetches this info from your class, and not the api directly you can work offline. When in offline mode, you can plug in some compatible 'fake' data to see it work.
Now you need to take this to the next level by making a wrapper type for every call you make to facebook. What I mean by this is that since you know what to expect from fb, you can pretend you actually got it, and proceed from there. Asking for a list of friend IDs? make a fake list that is reasonable, and have your application use it. Better still, generate as many fake offline users as you want, and make your server calls delay a random 'lag' time before returning the fake data to the event listener. This will also help test against possible race conditions.
One way to do this is by creating and extending a class to execute the api calls. Enjoy.
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
class MyApiCaller extends EventDispatcher{
//set up vars to hold call result data
protected var _someData:String;
//make sure to declare some event types for the callbacks
public static const SERVERCALL1_COMPLETE:String = "servercall1_complete";
function MyApiCaller(){
//init things....
}
public function doServerCall1(...args:*):void {
//create the ulrLoader etc...
//set up event listener to onServerCall1Complete
}
public function onServerCall1Complete(event:Event):void {
//parse results, save to vars
//fire event to notify the caller
dispatchEvent(new Event(SERVERCALL1_COMPLETE));
}
//getter to be used when the waiting object gets the SERVERCALL1_COMPLETE event
public function get someData():String {return _someData;}
}
class MyFakeApiCaller extends MyApiCaller{
//set up any additional types (random user data etc..) that would not be found in the base class
//no need to redeclare the event types
function MyFakeApiCaller(){
//init things....
}
override public function doServerCall1(...args:*):void {
//wait a random amount of time via Timer, set up event listener to onServerCall1Complete
}
override public function onServerCall1Complete(event:Event):void {
//event is a TimerEvent in this case
//generate data / choose random data
//save to vars: _someData = ...
//fire event to notify the caller
dispatchEvent(new Event(MyApiCaller.SERVERCALL1_COMPLETE));
}
//getter from base class will be used as usual
}
https://github.com/facebook/php-sdk plus http://www.apachefriends.org/en/xampp.html I believe is your best bet.