I need to design / architect / develop a web based social network type application.
Basic functionality:
- users create accounts on the system
- users agree to
You should first study the existing social networks out there (Facebook, Myspace, etc). There is a fair amount of information available about how they are implemented.
The key to success for social networks is not the technology on which it is based but the problems they solve for the users. If the users like it, you're doomed for success even if your technology is crap.
[EDIT] How is it implemented? Check any SQL-based user role system. In this case, every user is also a role which can be added as "allowed to access" to any object. Depending on how many objects you have and how fine grained the control should be, that can mean that you have a table with three columns: OBJECT, USER, ACCESS_TYPE
where ACCESS_TYPE
can be one of OWNER
, READ
(friend), WRITE
(close friend).
This table will become pretty large but a few 100 million rows is not uncommon for todays databases anymore.
In the end it looks like Elgg or Dolphin might meet our requirements. These appear to be PHP frameworks for rolling your own social network. I looked at the Facebook platform but nowhere did it clearly explain just what it is - it appears to be the facebook code but perhaps it is only the code for an addon API or something.
As Aaroon pointed out, you should first ask youself what problem you want to solve.
What content do you want people to share? Should it really be visible only to friends? It is much easier and scalable if you make content publicly visible, because what content is displayed is not dependent on who is watching the page and you can cache it easily. Publicly available user-generated content attracts new users.
If you want to restrict access and give to the user the opportunity to attach groups of friends to a resource I would go with a simple group-based access control. Let each resource have a group of users which can edit the resource and a group of users who can see it.
That way each resource has two single value attributes, and each user belons to a finite number of group. You can attach the view-group and edit-group attributes to a document stored in a NOSQL database, a search engine like Lucene/Sphinx or a row in a SQL database. When querying for content available for the user, pass all groups the user belongs to (in SQL you would use IN
clause, in Sphinx setFilter('view-group', array(2,3,4))
. The database would return only content available for the user. Because you are attaching only 2 integer values (view-group and edit-group) to a document, you can store them in memory which makes the search fast and scalable.
Your design should be maintenable. This is what I have in my project.
1.) Application.Infrastructure
2.) Application.DataModel
3.) Application.DataAccess
4.) Application.DomainObjects
5.) Application.BusinessLayer
6.) Application.WebClient or Application.WindowsClient
Application.BusinessObjects are used across the application and they travel across all layers whenever neeeded [except Application.DataModel and Application.Infrastructure]
All my queries are defined only Application.DataModel.
Application.DataAccess returns or takes Business objects as part of any data-access operation. Business objects are created with the help of reflection attributes. Each business object is marked with an attribute mapping to target table in database and properties within the business object are marked with attributes mapping to target coloumn in respective data-base table.
My validation framework lets me validate each field with the help of designated ValidationAttribute.
My framrwork heavily uses Attributes to automate most of the tedious tasks like mapping and validation. I can also new feature as new aspect in the framework.
A sample business object would look like this in my application.
User.cs
[TableMapping("Users")]
public class User : EntityBase
{
#region Constructor(s)
public AppUser()
{
BookCollection = new BookCollection();
}
#endregion
#region Properties
#region Default Properties - Direct Field Mapping using DataFieldMappingAttribute
private System.Int32 _UserId;
private System.String _FirstName;
private System.String _LastName;
private System.String _UserName;
private System.Boolean _IsActive;
[DataFieldMapping("UserID")]
[DataObjectFieldAttribute(true, true, false)]
[NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
public override int Id
{
get
{
return _UserId;
}
set
{
_UserId = value;
}
}
[DataFieldMapping("UserName")]
[Searchable]
[NotNullOrEmpty(Message = "Username Is Required.")]
public string UserName
{
get
{
return _UserName;
}
set
{
_UserName = value;
}
}
[DataFieldMapping("FirstName")]
[Searchable]
public string FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
[DataFieldMapping("LastName")]
[Searchable]
public string LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
[DataFieldMapping("IsActive")]
public bool IsActive
{
get
{
return _IsActive;
}
set
{
_IsActive = value;
}
}
#region One-To-Many Mappings
public BookCollection Books { get; set; }
#endregion
#region Derived Properties
public string FullName { get { return this.FirstName + " " + this.LastName; } }
#endregion
#endregion
public override bool Validate()
{
bool baseValid = base.Validate();
bool localValid = Books.Validate();
return baseValid && localValid;
}
}
BookCollection.cs
/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection()
{
}
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection (IList<Book> initialList)
: base(initialList)
{
}
}
First thing to get out the way is the database, an SQL one would just look like a normalised sql database. What else could it look like? A nosql database would look like a bunch of name value pair files.
Three approaches to building a social web site after and only after you do a shed load of research on existing popular and unpopular ones to ascertain their architecture and the markets that that they are aimed at, and the particular services that they offer to these markets.
How is "content visibility" handled. Initially of course the site builder makes a decision on who can see content. Owners only, friends, registered users, the general public? etc. But this decision must fir in with the aims and policies of the site. The best way then to handle this is through Role Based Access RBAC see here for details
When you say you "need to design / architect / develop" is this because of an overwhelming inner urge or because someone is paying you?
Either way remember the social web space is very very crowded. If you are just building another YouTube, or FaceBook then you are unlikely to be able to generate the critical mass of number required to make such a site commercially successful.
If it is for a niche market not already catered for, e.g. "The Peckham and Brockley Exotic Bird Fanciers Club" then you know what you market is and what features will be required so any of the above options you deem the easiest and cheapest can be used but that is up to you to analyse and execute.
You may of course have an idea for a social site that is mainstream and is not covered by the other, i.e. you have spotted the mythological "gap in the market". In this case go for it but prepare to be disappointed. Or not.