the data model
the entities
public class tag { public int id { get; set; } public string name { get; set; } public string urlslug { get; set; } } public class category { public int id { get; set; } public string name { get; set; } public string urlslug { get; set; } } public class post { public int id { get; set; } public string title { get; set; } public string urlslug { get; set; } public string tnimage { get; set; } public string author { get; set; } public list<tag> tags { get; set; } public category category { get; set; } public string datepublished { get; set; } public string datecreated { get; set; } public string datemodified { get; set; } public string description { get; set; } public string articlebody { get; set; } }
i'm using entity-framework against sql server compact embedded db, , have written generic repository crud operations against individual entities post
, category
, tag
etc.
all works fine.
i'm writing asp.net web api expose crud via rest-ful api.
the rest api end points
╔═══════╦═══════════════════════╦════════════════════════════════════╗ ║ verb ║ end point ║ description ║ ╠═══════╬═══════════════════════╬════════════════════════════════════╣ ║ ║ /api/tags ║ returns tags ║ ║ ║ /api/tags/tips ║ returns single tag (name=tips) ║ ║ post ║ /api/tags ║ creates new tag ║ ║ ║ /api/categories ║ returns categories ║ ║ ║ /api/categories/news ║ returns single category (name=news)║ ║ post ║ /api/categories ║ creates new category ║ ║ ║ /api/posts ║ returns post ║ ║ ║ /api/posts/51 ║ returns single post (id=51) ║ ║ ║ /api/posts/2/tags ║ returns tags post w/ id=2 ║ ║ ║ /api/posts/2/category ║ returns category post w/ id=2 ║ ║ post ║ /api/posts ║ creates new post ║ ╚═══════╩═══════════════════════╩════════════════════════════════════╝
the situation
when create post
entity doing post
request against /api/posts
endpoint , have post
entities data in body json, potentially have 1
or more tag instances, , 0
or 1
category.
sample post
body blog post
{ "title": "how 6 pack abs in 6 days", "urlslug": "6-pack-abs-6-days", "tnimage": "http:\/\/example.com\/image.jpg", "author": "john doe", "tags": [ { "name": "6 pack abs tips" }, { "name": "exercise tips" }, { "name": "workout videos" } ], "category": { "name": "fitness" }, "datepublished": "2017-04-01", "datecreated": "2015-01-20", "datemodified": "2017-04-01", "description": "seo keyword stuffed description fake tips abs here", "articlebody": "full post body containing fake tips 6 packs. html" }
of these tags, may exist, , may not. ones don't exist need created. , tags need created, urlslug
generated using helper method.
the category, if filled, should inserted if doesn't exist.
the question
given scenario, how had post
request against /api/posts
endpoint, , ensure related tag
, category
entities added if don't exist?
if sample post shown above posted endpoint, how handle adding tags don't exist, category if doesn't exist, , adding new post?
also, approaching wrong in terms of rest design? if yes, recommended approach ensure data isn't inconsistent, i.e. tags added error occurs, there orphans now.
public class postscontroller : apicontroller { [route("api/posts")] [httppost] public ihttpactionresult post([frombody]postdto post) { try { if (post == null) { return badrequest(); } // goes in here, add tags don't exist, // category if doesn't exist // , create post. add methods call repo methods // // there other way, i.e. approaching wrong? } catch (exception) { return internalservererror(); } }
a sample solution can here:
using (var context = new yourcontext()) { //find or create category category category = null; if (context.categories.any(cat => cat.name == post.category.name)) { category = context.categories.firstordefault(cat => cat.name == post.category.name); } else { category = new category { name = post.category.name }; context.categories.add(category); } //find or create tags var tags = new list<tag>(); foreach (var tag in post.tags) { tag targetedtag; if (context.tags.any(t => t.name == tag.name)) { targetedtag = context.tags.firstordefault(t => t.name == tag.name); } else { targetedtag = new tag { name = tag.name, // urlslug = use helper you've said }; context.tags.add(targetedtag); } tags.add(targetedtag); } var targetedpost = new post { category = category, tags = tags, articlebody = post.articlebody, author = post.author, datecreated = post.datecreated, datemodified = post.datemodified, datepublished = post.datepublished, description = post.description, title = post.title, tnimage = post.tnimage, urlslug = post.urlslug }; context.posts.add(targetedpost); context.savechanges(); }
Comments
Post a Comment