Skip to content

Documentation updates for v4 #741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ See the [examples](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/mas

## Installation And Usage

See [the documentation](https://json-api-dotnet.github.io/#/) for detailed usage.
See [the documentation](https://json-api-dotnet.github.io/#/) for detailed usage.

### Models

Expand All @@ -56,7 +56,7 @@ public class ArticlesController : JsonApiController<Article>
public ArticlesController(
IJsonApiOptions jsonApiOptions,
IResourceService<Article> resourceService,
ILoggerFactory loggerFactory)
ILoggerFactory loggerFactory)
: base(jsonApiOptions, resourceService, loggerFactory)
{ }
}
Expand All @@ -65,7 +65,7 @@ public class ArticlesController : JsonApiController<Article>
### Middleware

```csharp
public class Startup
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services) {
services.AddJsonApi<AppDbContext>();
Expand All @@ -89,7 +89,7 @@ dotnet restore

#### Testing

Running tests locally requires access to a PostgreSQL database. If you have docker installed, this can be propped up via:
Running tests locally requires access to a PostgreSQL database. If you have docker installed, this can be propped up via:

```bash
docker run --rm --name jsonapi-dotnet-core-testing -e POSTGRES_DB=JsonApiDotNetCoreExample -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:12.0
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
```
./generate.sh
docfx ./docfx.json --serve
```
```
3 changes: 1 addition & 2 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ This section documents the package API and is generated from the XML source comm
## Common APIs

- [`JsonApiOptions`](JsonApiDotNetCore.Configuration.JsonApiOptions.html)
- [`IResourceGraph`](JsonApiDotNetCore.Internal.IResourceGraph.html)
- [`IResourceGraph`](JsonApiDotNetCore.Internal.Contracts.IResourceGraph.html)
- [`ResourceDefinition<T>`](JsonApiDotNetCore.Models.ResourceDefinition-1.html)
- [`IQueryAccessor`](JsonApiDotNetCore.Services.IQueryAccessor.html)
9 changes: 0 additions & 9 deletions docs/generators/index.md

This file was deleted.

16 changes: 0 additions & 16 deletions docs/getting-started/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,3 @@ Install-Package JsonApiDotnetCore
<PackageReference Include="JsonApiDotNetCore" Version="3.0.0" />
</ItemGroup>
```

## Pre-Release Packages

Occasionally we will release experimental features as pre-release packages on our
MyGet feed. You can download these by adding [the pacakge feed](https://www.myget.org/feed/Details/research-institute) to your nuget configuration.

These releases are deployed from the `develop` branch directly.

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="JADNC Pre-Release" value="https://www.myget.org/F/research-institute/api/v3/index.json" />
</packageSources>
</configuration>
```
56 changes: 29 additions & 27 deletions docs/getting-started/step-by-step.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Step-By-Step Guide to a Running API

The most basic use case leverages Entity Framework.
The most basic use case leverages Entity Framework Core.
The shortest path to a running API looks like:

- Create a new web app
Expand Down Expand Up @@ -33,45 +33,45 @@ Install-Package JsonApiDotnetCore
```

### Define Models

Define your domain models such that they implement `IIdentifiable<TId>`.
The easiest way to do this is to inherit `Identifiable`
The easiest way to do this is to inherit from `Identifiable`

```c#
public class Person : Identifiable
{
{
[Attr("name")]
public string Name { get; set; }
}
```

### Define DbContext

Nothing special here, just an ordinary `DbContext`

```
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }

public DbSet<Person> People { get; set; }
}
```

### Define Controllers
You need to create controllers that inherit from `JsonApiController<TEntity>` or `JsonApiController<TEntity, TId>`
where `TEntity` is the model that inherits from `Identifiable<TId>`

You need to create controllers that inherit from `JsonApiController<T>` or `JsonApiController<T, TId>`
where `T` is the model that inherits from `Identifiable<TId>`

```c#
public class PeopleController : JsonApiController<Person>
{
public PeopleController(
IJsonApiContext jsonApiContext,
IResourceService<Person> resourceService,
ILoggerFactory loggerFactory)
: base(jsonApiContext, resourceService, loggerFactory)
IJsonApiOptions jsonApiOptions,
ILoggerFactory loggerFactory,
IResourceService<Person> resourceService)
: base(jsonApiOptions, loggerFactory, resourceService)
{ }
}
```
Expand All @@ -81,24 +81,26 @@ public class PeopleController : JsonApiController<Person>
Finally, add the services by adding the following to your Startup.ConfigureServices:

```c#
public IServiceProvider ConfigureServices(IServiceCollection services)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// add the db context like you normally would
// Add the Entity Framework Core DbContext like you normally would
services.AddDbContext<AppDbContext>(options =>
{ // use whatever provider you want, this is just an example
{
// Use whatever provider you want, this is just an example
options.UseNpgsql(GetDbConnectionString());
}, ServiceLifetime.Transient);
});

// add jsonapi dotnet core
// Add JsonApiDotNetCore
services.AddJsonApi<AppDbContext>();
// ...
}
```

Add the middleware to the Startup.Configure method. Note that under the hood,
this will call `app.UseMvc()` so there is no need to add that as well.
Add the middleware to the Startup.Configure method. Note that under the hood,
this will call `app.UseRouting()` and `app.UseEndpoints(...)` so there is no need to add that as well.

```c#
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseJsonApi();
Expand All @@ -110,19 +112,19 @@ public void Configure(IApplicationBuilder app)
One way to seed the database is in your Configure method:

```c#
public void Configure(
IApplicationBuilder app,
AppDbContext context)
public void Configure(IApplicationBuilder app, AppDbContext context)
{
context.Database.EnsureCreated();
if(context.People.Any() == false)

if (!context.People.Any())
{
context.People.Add(new Person {
context.People.Add(new Person
{
Name = "John Doe"
});
context.SaveChanges();
}
// ...

app.UseJsonApi();
}
```
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ A [{ json:api }](https://jsonapi.org) web application framework for .Net Core.

### 1. Eliminate Boilerplate

The goal of this package is to facility the development of json:api applications that leverage the full range
The goal of this package is to facility the development of json:api applications that leverage the full range
of features provided by the specification.

Eliminate CRUD boilerplate and provide the following features across all your resource endpoints:
Eliminate CRUD boilerplate and provide the following features across all your resource endpoints:

- Relationship inclusion and navigation
- Filtering
Expand Down
1 change: 0 additions & 1 deletion docs/request-examples/000-CREATE_Person.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
curl -vs http://localhost:5001/api/people \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
Expand Down
1 change: 0 additions & 1 deletion docs/request-examples/001-CREATE_Article.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
curl -vs http://localhost:5001/api/articles \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
Expand Down
3 changes: 1 addition & 2 deletions docs/request-examples/002-GET_Articles.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
curl -vs http://localhost:5001/api/articles \
-H "Accept: application/vnd.api+json"
curl -vs http://localhost:5001/api/articles
3 changes: 1 addition & 2 deletions docs/request-examples/003-GET_Article.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
curl -vs http://localhost:5001/api/articles/1 \
-H "Accept: application/vnd.api+json"
curl -vs http://localhost:5001/api/articles/1
3 changes: 1 addition & 2 deletions docs/request-examples/004-GET_Articles_With_Authors.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
curl -vs http://localhost:5001/api/articles?include=author \
-H "Accept: application/vnd.api+json"
curl -vs http://localhost:5001/api/articles?include=author
3 changes: 1 addition & 2 deletions docs/request-examples/005-PATCH_Article.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
curl -vs http://localhost:5001/api/people/1 \
-H "Accept: application/vnd.api+json" \
curl -vs http://localhost:5001/api/people/1 \
-H "Content-Type: application/vnd.api+json" \
-X PATCH \
-d '{
Expand Down
1 change: 0 additions & 1 deletion docs/request-examples/006-DELETE_Article.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
curl -vs http://localhost:5001/api/articles/1 \
-H "Accept: application/vnd.api+json" \
-X DELETE
2 changes: 0 additions & 2 deletions docs/request-examples/007-__SEED__.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
curl -vs http://localhost:5001/api/people \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
Expand All @@ -11,7 +10,6 @@ curl -vs http://localhost:5001/api/people \
}'

curl -vs http://localhost:5001/api/articles \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
Expand Down
3 changes: 1 addition & 2 deletions docs/request-examples/008-GET_Articles_With_Filter_Eq.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
curl -vs http://localhost:5001/api/articles?filter%5Btitle%5D=Moby \
-H "Accept: application/vnd.api+json"
curl -vs http://localhost:5001/api/articles?filter%5Btitle%5D=Moby
3 changes: 1 addition & 2 deletions docs/request-examples/009-GET_Articles_With_Filter_Like.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
curl -vs http://localhost:5001/api/people?filter%5Bname%5D=like:Al \
-H "Accept: application/vnd.api+json"
curl -vs http://localhost:5001/api/people?filter%5Bname%5D=like:Al
3 changes: 1 addition & 2 deletions docs/request-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ To update these requests:

1. Add a bash (.sh) file prefixed by a number that is used to determine the order the scripts are executed. The bash script should execute a request and output the response. Example:
```
curl -vs http://localhost:5001/api/articles \
-H "Accept: application/vnd.api+json"
curl -vs http://localhost:5001/api/articles
```

2. Add the example to `index.md`. Example:
Expand Down
70 changes: 14 additions & 56 deletions docs/usage/errors.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,25 @@
# Errors

By default, errors will only contain the properties defined by the `Error` class.
However, you can create your own by inheriting from Error and either throwing it in a `JsonApiException` or returning the error from your controller.
Errors returned will contain only the properties that are set on the `Error` class. Custom fields can be added through `Error.Meta`.
You can create a custom error by throwing a `JsonApiException` (which accepts an `Error` instance), or returning an `Error` instance from an `ActionResult` in a controller.
Please keep in mind that json:api requires Title to be a generic message, while Detail should contain information about the specific problem occurence.

From a controller method:
```c#
public class CustomError : Error
return Conflict(new Error(HttpStatusCode.Conflict)
{
public CustomError(int status, string title, string detail, string myProp)
: base(status, title, detail)
{
MyCustomProperty = myProp;
}

public string MyCustomProperty { get; set; }
}
Title = "Target resource was modified by another user.",
Detail = $"User {userName} changed the {resourceField} field on the {resourceName} resource."
});
```

If you throw a `JsonApiException` that is unhandled, the middleware will properly serialize it and return it as a json:api error.

From other code:
```c#
public void MyMethod()
throw new JsonApiException(new Error(HttpStatusCode.Conflict)
{
var error = new CustomError(507, "title", "detail", "custom");
throw new JsonApiException(error);
}
Title = "Target resource was modified by another user.",
Detail = $"User {userName} changed the {resourceField} field on the {resourceName} resource."
});
```

You can use the `IActionResult Error(Error error)` method to return a single error message, or you can use the `IActionResult Errors(ErrorCollection errors)` method to return a collection of errors from your controller.

```c#
[HttpPost]
public override async Task<IActionResult> PostAsync([FromBody] MyEntity entity)
{
if(_db.IsFull)
return Error(new CustomError("507", "Database is full.", "Theres no more room.", "Sorry."));

if(model.Validations.IsValid == false)
return Errors(model.Validations.GetErrors());
}
```

## Example: Including Links

This example demonstrates one way you can include links with your error payloads.

This example assumes that there is a support documentation site that provides additional information based on the HTTP Status Code.

```c#
public class LinkableError : Error
{
public LinkableError(int status, string title)
: base(status, title)
{ }

public ErrorLink Links => "https://example.com/errors/" + Status;
}

var error = new LinkableError(401, "You're not allowed to do that.");
throw new JsonApiException(error);
```






In both cases, the middleware will properly serialize it and return it as a json:api error.
Loading